From ad9059e58ff0ae9589d9d384ad1c70ec72649d99 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wies=C5=82aw=20S=CC=8Colte=CC=81s?= Date: Wed, 25 Dec 2024 18:47:00 +0100 Subject: [PATCH 01/10] Fix checks --- ReactiveGenerator/ReactiveGenerator.cs | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/ReactiveGenerator/ReactiveGenerator.cs b/ReactiveGenerator/ReactiveGenerator.cs index 0e414eb..6578229 100644 --- a/ReactiveGenerator/ReactiveGenerator.cs +++ b/ReactiveGenerator/ReactiveGenerator.cs @@ -11,6 +11,9 @@ namespace ReactiveGenerator; [Generator] public class ReactiveGenerator : IIncrementalGenerator { + private static INamedTypeSymbol? s_reactiveAttributeSymbol; + private static INamedTypeSymbol? s_ignoreReactiveAttributeSymbol; + private record PropertyInfo( IPropertySymbol Property, bool HasReactiveAttribute, @@ -19,13 +22,25 @@ private record PropertyInfo( public void Initialize(IncrementalGeneratorInitializationContext context) { - // Register both attributes context.RegisterPostInitializationOutput(ctx => { ctx.AddSource("ReactiveAttribute.g.cs", SourceText.From(AttributeSource, Encoding.UTF8)); ctx.AddSource("IgnoreReactiveAttribute.g.cs", SourceText.From(IgnoreAttributeSource, Encoding.UTF8)); }); + // Cache known attribute symbols + var compilationProvider = context.CompilationProvider.Select((comp, _) => + { + s_reactiveAttributeSymbol = comp.GetTypeByMetadataName("ReactiveAttribute"); + // or if your attribute is in a namespace, e.g. "MyNamespace.ReactiveAttribute", + // use that full name instead: + // s_reactiveAttributeSymbol = comp.GetTypeByMetadataName("MyNamespace.ReactiveAttribute"); + + s_ignoreReactiveAttributeSymbol = comp.GetTypeByMetadataName("IgnoreReactiveAttribute"); + // ... + return comp; + }); + // Get MSBuild property for enabling legacy mode var useLegacyMode = context.AnalyzerConfigOptionsProvider .Select((provider, _) => bool.TryParse( @@ -69,21 +84,20 @@ public void Initialize(IncrementalGeneratorInitializationContext context) private static bool IsTypeReactive(INamedTypeSymbol type) { - // If type inherits from ReactiveObject, it's already reactive if (InheritsFromReactiveObject(type)) return true; - // First check if the type has [IgnoreReactive] + // Check for [IgnoreReactive] foreach (var attribute in type.GetAttributes()) { - if (attribute.AttributeClass?.Name is "IgnoreReactiveAttribute" or "IgnoreReactive") + if (SymbolEqualityComparer.Default.Equals(attribute.AttributeClass, s_ignoreReactiveAttributeSymbol)) return false; } - // Then check if the type has [Reactive] + // Check for [Reactive] foreach (var attribute in type.GetAttributes()) { - if (attribute.AttributeClass?.Name is "ReactiveAttribute" or "Reactive") + if (SymbolEqualityComparer.Default.Equals(attribute.AttributeClass, s_reactiveAttributeSymbol)) return true; } From 9af6f6f885563ac19f5fa39b143988d5392fb9b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wies=C5=82aw=20S=CC=8Colte=CC=81s?= Date: Wed, 25 Dec 2024 19:17:06 +0100 Subject: [PATCH 02/10] Create CrossAssemblyTests.cs --- ReactiveGenerator.Tests/CrossAssemblyTests.cs | 176 ++++++++++++++++++ 1 file changed, 176 insertions(+) create mode 100644 ReactiveGenerator.Tests/CrossAssemblyTests.cs diff --git a/ReactiveGenerator.Tests/CrossAssemblyTests.cs b/ReactiveGenerator.Tests/CrossAssemblyTests.cs new file mode 100644 index 0000000..5fb50e8 --- /dev/null +++ b/ReactiveGenerator.Tests/CrossAssemblyTests.cs @@ -0,0 +1,176 @@ +using Xunit; +using System.Threading.Tasks; +using System.Collections.Generic; + +namespace ReactiveGenerator.Tests +{ + public class CrossAssemblyTests + { + /// + /// 1) External assembly: [Reactive] base class physically gets INPC from the generator + /// Main assembly: derived class sees that the base already has INPC => no second partial generated. + /// + [Fact] + public Task ExternalBaseHasReactiveClass_ThenNoDoubleINPCInDerived() + { + var externalAssemblySource = @" +using System; + +namespace ExternalLib +{ + [Reactive] + public partial class ExternalBase + { + public partial string ExternalProp { get; set; } + } +} +"; + var mainAssemblySource = @" +using ExternalLib; + +namespace MainLib +{ + // Derived class also has [Reactive] property + // but won't generate a second INPC partial if the base physically has it. + public partial class DerivedClass : ExternalBase + { + [Reactive] + public partial int LocalProp { get; set; } + } +} +"; + + return SourceGeneratorTestHelper.TestCrossAssemblyAndVerifyWithExternalGen( + externalAssemblySource, + mainAssemblySource, + // optional config: + // new Dictionary { ["build_property.UseBackingFields"] = "true" }, + null, + new ReactiveGenerator() + ); + } + + /// + /// 2) External assembly: base class has [Reactive], plus [IgnoreReactive] on some property. + /// Main assembly: derived class => we confirm no double INPC, and ignored property remains ignored. + /// + [Fact] + public Task ExternalBaseHasIgnoreReactive_ThenDerivedIgnoresItToo() + { + var externalAssemblySource = @" +using System; + +namespace ExternalLib +{ + [Reactive] + public partial class BaseWithIgnore + { + [IgnoreReactive] + public partial string IgnoredProp { get; set; } + + public partial string NormalProp { get; set; } + } +} +"; + var mainAssemblySource = @" +using ExternalLib; + +namespace MainLib +{ + public partial class DerivedIgnore : BaseWithIgnore + { + // This is local partial. We'll see no duplication of INPC, + // and 'IgnoredProp' won't generate in external or derived code. + [Reactive] + public partial string ExtraProp { get; set; } + } +} +"; + + return SourceGeneratorTestHelper.TestCrossAssemblyAndVerifyWithExternalGen( + externalAssemblySource, + mainAssemblySource, + null, // or new Dictionary { ... }, + new ReactiveGenerator() + ); + } + + [Fact] + public Task ExternalBaseHasPropertyLevelReactive_ThenNoExtraINPCInDerived() + { + var externalAssemblySource = @" +using System; + +namespace ExternalLib +{ + public partial class ExternalMixed + { + [Reactive] + public partial string ExternalReactiveProp { get; set; } + + public partial string ExternalNonReactiveProp { get; set; } + } +}"; + + var mainAssemblySource = @" +using ExternalLib; + +namespace MainLib +{ + public partial class LocalDerived : ExternalMixed + { + [Reactive] + public partial int LocalReactiveProp { get; set; } + } +}"; + return SourceGeneratorTestHelper.TestCrossAssemblyAndVerifyWithExternalGen( + externalAssemblySource, + mainAssemblySource, + null, + new ReactiveGenerator()); + } + + /// + /// 4) External assembly: class inherits from ReactiveObject (assuming we have ReactiveUI available). + /// So it already physically has INPC => main assembly sees that and won't generate again. + /// + [Fact] + public Task ExternalBaseDerivedFromReactiveObject_ThenNoDoubleINPCInDerived() + { + // For this test to run, you'd typically need a ref to ReactiveUI or a mock ReactiveObject in the test references. + // If you don't have ReactiveObject, just remove this example. + var externalAssemblySource = @" +using System; +using ReactiveUI; + +namespace ExternalLib +{ + public partial class ExternalViewModel : ReactiveObject + { + // Even without [Reactive], ReactiveObject base means we won't generate a new INPC partial. + public partial string SomeProp { get; set; } + } +} +"; + var mainAssemblySource = @" +using ExternalLib; + +namespace MainLib +{ + public partial class ChildViewModel : ExternalViewModel + { + [Reactive] + public partial int AnotherProp { get; set; } + } +} +"; + + return SourceGeneratorTestHelper.TestCrossAssemblyAndVerifyWithExternalGen( + externalAssemblySource, + mainAssemblySource, + null, + new ReactiveGenerator() + ); + } + } +} From 6f19630011cd7737305d2bdae8a19bd67db1c015 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wies=C5=82aw=20S=CC=8Colte=CC=81s?= Date: Wed, 25 Dec 2024 19:17:10 +0100 Subject: [PATCH 03/10] Update SourceGeneratorTestHelper.cs --- .../SourceGeneratorTestHelper.cs | 167 +++++++++++++++--- 1 file changed, 145 insertions(+), 22 deletions(-) diff --git a/ReactiveGenerator.Tests/SourceGeneratorTestHelper.cs b/ReactiveGenerator.Tests/SourceGeneratorTestHelper.cs index bc50611..1c934f6 100644 --- a/ReactiveGenerator.Tests/SourceGeneratorTestHelper.cs +++ b/ReactiveGenerator.Tests/SourceGeneratorTestHelper.cs @@ -3,11 +3,70 @@ using Microsoft.CodeAnalysis.Diagnostics; using System.ComponentModel; using System.Runtime.CompilerServices; +using System.Collections.Immutable; namespace ReactiveGenerator.Tests; public static class SourceGeneratorTestHelper { + /// + /// A specialized cross-assembly test method that actually runs the same generators + /// on the external assembly first, ensuring any [Reactive] classes in the external + /// assembly get physically compiled with INotifyPropertyChanged. + /// + /// Then references that compiled assembly from the main assembly, so the derived + /// class sees that the base physically has INPC, and thus won't generate a second partial. + /// +public static async Task TestCrossAssemblyAndVerifyWithExternalGen( + string externalAssemblySource, + string mainAssemblySource, + Dictionary? analyzerConfigOptions = null, + params IIncrementalGenerator[] generators) +{ + // 1. Build external assembly + var externalCompilation = CreateCompilation(externalAssemblySource, "ExternalAssembly"); + // 2. Create generator driver + GeneratorDriver extDriver = CSharpGeneratorDriver.Create( + generators.Select(g => g.AsSourceGenerator()), + parseOptions: (CSharpParseOptions)externalCompilation.SyntaxTrees.First().Options, + optionsProvider: analyzerConfigOptions != null + ? new DictionaryAnalyzerConfigOptionsProvider(analyzerConfigOptions) + : null); + + // 3. Run on external assembly + extDriver = extDriver.RunGenerators(externalCompilation); + + var extRunResult = extDriver.GetRunResult(); + + // 4. Add newly generated syntax trees => includes .ReactiveProperties.g.cs + externalCompilation = externalCompilation.AddSyntaxTrees(extRunResult.GeneratedTrees); + + // (Optional) you can re-check for newly discovered partials, but typically once is enough. + + // 5. Create reference from the updated external compilation + var externalReference = externalCompilation.ToMetadataReference(); + + // 6. Create main assembly referencing the updated external assembly + var mainCompilation = CreateCompilation(mainAssemblySource, "MainAssembly", externalReference); + + // 7. Run generator on the main assembly + GeneratorDriver mainDriver = CSharpGeneratorDriver.Create( + generators.Select(g => g.AsSourceGenerator()), + parseOptions: (CSharpParseOptions)mainCompilation.SyntaxTrees.First().Options, + optionsProvider: analyzerConfigOptions != null + ? new DictionaryAnalyzerConfigOptionsProvider(analyzerConfigOptions) + : null); + + mainDriver = mainDriver.RunGenerators(mainCompilation); + + // 8. Verify final results + await Verify(mainDriver); +} + + + /// + /// Single-assembly test entry point (existing). + /// public static Task TestAndVerify( string source, Dictionary? analyzerConfigOptions = null, @@ -19,65 +78,126 @@ public static Task TestAndVerify( throw new ArgumentException("At least one generator must be provided", nameof(generators)); } - // Create compilation + // Create single-assembly compilation var compilation = CreateCompilation(source); - - // Create the driver with generators and options + + // Create the driver with generators and config GeneratorDriver driver = CSharpGeneratorDriver.Create( generators.Select(g => g.AsSourceGenerator()), parseOptions: (CSharpParseOptions)compilation.SyntaxTrees.First().Options, - optionsProvider: analyzerConfigOptions != null - ? new DictionaryAnalyzerConfigOptionsProvider(analyzerConfigOptions) + optionsProvider: analyzerConfigOptions != null + ? new DictionaryAnalyzerConfigOptionsProvider(analyzerConfigOptions) : null); // Run generation driver = driver.RunGenerators(compilation); - // Use our verify helper + // Verify + return Verify(driver); + } + + /// + /// NEW: Cross-assembly testing for scenarios where a base class (with or without [Reactive]) + /// resides in a separate assembly. + /// + /// Source code for the external assembly (defines base, attributes, etc.) + /// Source code for the main assembly that references the external assembly. + /// Optional analyzer config (e.g. UseBackingFields=true). + /// Your incremental generators. + /// + public static Task TestCrossAssemblyAndVerify( + string externalAssemblySource, + string mainAssemblySource, + Dictionary? analyzerConfigOptions = null, + params IIncrementalGenerator[] generators) + { + if (generators == null || generators.Length == 0) + { + throw new ArgumentException("At least one generator must be provided", nameof(generators)); + } + + // 1. Create external assembly + var externalCompilation = CreateCompilation( + externalAssemblySource, + assemblyName: "ExternalAssembly"); + + // 2. Create main assembly that references external assembly + var mainCompilation = CreateCompilation( + mainAssemblySource, + assemblyName: "MainAssembly", + externalCompilation.ToMetadataReference() + ); + + // 3. Create the driver + GeneratorDriver driver = CSharpGeneratorDriver.Create( + generators.Select(g => g.AsSourceGenerator()), + parseOptions: (CSharpParseOptions)mainCompilation.SyntaxTrees.First().Options, + optionsProvider: analyzerConfigOptions != null + ? new DictionaryAnalyzerConfigOptionsProvider(analyzerConfigOptions) + : null); + + // 4. Run generator on main assembly + driver = driver.RunGenerators(mainCompilation); + + // 5. Verify return Verify(driver); } - private static Compilation CreateCompilation(string source) + /// + /// Helper to create a CSharpCompilation from source. + /// + private static CSharpCompilation CreateCompilation( + string source, + string assemblyName = "TestAssembly", + params MetadataReference[] additionalReferences) { - var syntaxTree = CSharpSyntaxTree.ParseText(source); - var references = new[] + var syntaxTree = CSharpSyntaxTree.ParseText( + source, + new CSharpParseOptions(LanguageVersion.Latest)); + + var references = new List { MetadataReference.CreateFromFile(typeof(object).Assembly.Location), MetadataReference.CreateFromFile(typeof(Attribute).Assembly.Location), MetadataReference.CreateFromFile(typeof(INotifyPropertyChanged).Assembly.Location), - // Add ReactiveUI reference if needed for your tests - // MetadataReference.CreateFromFile(typeof(ReactiveObject).Assembly.Location) + // If you need ReactiveUI or other references, add them similarly: + // MetadataReference.CreateFromFile(typeof(ReactiveObject).Assembly.Location), }; + references.AddRange(additionalReferences); var compilation = CSharpCompilation.Create( - assemblyName: "TestAssembly", - syntaxTrees: new[] { syntaxTree }, - references: references, - options: new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary)); + assemblyName, + new[] { syntaxTree }, + references, + new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary)); return compilation; } + /// + /// Reuses your existing verification approach. + /// private static Task Verify(GeneratorDriver driver) { var runResults = driver.GetRunResult(); - // Get the generated sources from the compilation + // Gather generated sources var generatedSources = runResults.GeneratedTrees .Select(tree => new { FileName = Path.GetFileName(tree.FilePath), Source = tree.ToString() }) - .OrderBy(f => f.FileName) + .OrderBy(x => x.FileName) .ToList(); - if (!generatedSources.Any()) - { - throw new Exception("No source was generated!"); - } + // Optionally check if no sources were generated: + // if (!generatedSources.Any()) + // { + // throw new Exception("No source was generated!"); + // } - // Return results in a verifiable format + // Return the verification structure return Verifier.Verify(new { Sources = generatedSources, @@ -86,6 +206,9 @@ private static Task Verify(GeneratorDriver driver) } } +/// +/// Simple dictionary-based analyzer config. +/// public class DictionaryAnalyzerConfigOptionsProvider : AnalyzerConfigOptionsProvider { private readonly DictionaryAnalyzerConfigOptions _options; From cb015d53fadbb556a05f7e283e807e21f0d8b6a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wies=C5=82aw=20S=CC=8Colte=CC=81s?= Date: Wed, 25 Dec 2024 19:17:16 +0100 Subject: [PATCH 04/10] Update ReactiveGenerator.cs --- ReactiveGenerator/ReactiveGenerator.cs | 47 ++++++++++++++++---------- 1 file changed, 30 insertions(+), 17 deletions(-) diff --git a/ReactiveGenerator/ReactiveGenerator.cs b/ReactiveGenerator/ReactiveGenerator.cs index 6578229..2e1adcf 100644 --- a/ReactiveGenerator/ReactiveGenerator.cs +++ b/ReactiveGenerator/ReactiveGenerator.cs @@ -293,12 +293,12 @@ private static void Execute( var processedTypes = new HashSet(SymbolEqualityComparer.Default); var allTypes = new HashSet(SymbolEqualityComparer.Default); - // Group properties by containing type + // Group partial properties by containing type var propertyGroups = properties .GroupBy(p => p.Property.ContainingType, SymbolEqualityComparer.Default) .ToDictionary(g => g.Key, g => g.ToList(), SymbolEqualityComparer.Default); - // Add types that need processing + // Gather all candidate types from the compilation foreach (var type in GetAllTypesInCompilation(compilation)) { if (IsTypeMarkedReactive(type) || HasAnyReactiveProperties(type, propertyGroups)) @@ -307,22 +307,30 @@ private static void Execute( } } - // Process types in correct order + // Sort types so base classes come before derived foreach (var type in allTypes.OrderBy(t => GetTypeHierarchyDepth(t))) { if (processedTypes.Contains(type)) continue; - var isReactiveObjectDerived = InheritsFromReactiveObject(type); + // If the class or any of its base types physically inherits from ReactiveObject, + // we won't generate an INotifyPropertyChanged partial + bool isReactiveObjectDerived = InheritsFromReactiveObject(type); - // Generate INPC implementation if needed - if (!isReactiveObjectDerived && !HasINPCImplementation(compilation, type, processedTypes)) + // Check if the type or base types physically implement INotifyPropertyChanged, + // or if we've already processed them in this compilation + bool alreadyHasInpc = isReactiveObjectDerived || + HasINPCImplementation(compilation, type, processedTypes); + + // If not already present, create the INPC partial + if (!alreadyHasInpc) { var inpcSource = GenerateINPCImplementation(type); if (!string.IsNullOrEmpty(inpcSource)) { var fullTypeName = type.ToDisplayString(new SymbolDisplayFormat( - typeQualificationStyle: SymbolDisplayTypeQualificationStyle.NameAndContainingTypesAndNamespaces, + typeQualificationStyle: SymbolDisplayTypeQualificationStyle + .NameAndContainingTypesAndNamespaces, genericsOptions: SymbolDisplayGenericsOptions.None, miscellaneousOptions: SymbolDisplayMiscellaneousOptions.None)); @@ -331,20 +339,22 @@ private static void Execute( } } - // Generate property implementations + // Generate property partials for [Reactive] or class-level [Reactive] + // (skipping those with [IgnoreReactive], or that have an existing implementation) if (propertyGroups.TryGetValue(type, out var typeProperties)) { - var isTypeReactive = IsTypeMarkedReactive(type); + bool isTypeReactive = IsTypeMarkedReactive(type); + var reactiveProperties = typeProperties .Where(p => !p.HasImplementation && !p.HasIgnoreAttribute && - (p.HasReactiveAttribute || // Include properties marked with [Reactive] - isTypeReactive)) // Include all properties if class is marked with [Reactive] + (p.HasReactiveAttribute || isTypeReactive)) .Select(p => p.Property) .ToList(); if (reactiveProperties.Any()) { + // We do *not* generate a second INPC block here, just the property expansions var source = GenerateClassSource( type, reactiveProperties, @@ -369,30 +379,33 @@ private static void Execute( } } - private static bool HasINPCImplementation(Compilation compilation, INamedTypeSymbol typeSymbol, + private static bool HasINPCImplementation( + Compilation compilation, + INamedTypeSymbol typeSymbol, HashSet processedTypes) { var inpcType = compilation.GetTypeByMetadataName("System.ComponentModel.INotifyPropertyChanged"); if (inpcType is null) return false; - // First check if current type implements INPC directly + // 1. If the type physically implements INPC via AllInterfaces if (typeSymbol.AllInterfaces.Contains(inpcType, SymbolEqualityComparer.Default)) return true; - // Check if current type is in processedTypes (will have INPC implemented) + // 2. If the generator has *already* processed this type in this compilation + // (thus added a partial INPC), it effectively has INPC. if (processedTypes.Contains(typeSymbol)) return true; - // Check base types recursively + // 3. Check base types recursively var current = typeSymbol.BaseType; while (current is not null) { - // Check if base type implements INPC directly + // If the base physically implements INPC if (current.AllInterfaces.Contains(inpcType, SymbolEqualityComparer.Default)) return true; - // Check if base type is in processedTypes + // If the base was processed by this generator if (processedTypes.Contains(current)) return true; From 7e6d0aa54f32c12d15ac1cca7e236828a613a681 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wies=C5=82aw=20S=CC=8Colte=CC=81s?= Date: Wed, 25 Dec 2024 19:28:39 +0100 Subject: [PATCH 05/10] Update ReactiveGenerator.cs --- ReactiveGenerator/ReactiveGenerator.cs | 100 ++++++++++++++++++++++--- 1 file changed, 88 insertions(+), 12 deletions(-) diff --git a/ReactiveGenerator/ReactiveGenerator.cs b/ReactiveGenerator/ReactiveGenerator.cs index 2e1adcf..41c6430 100644 --- a/ReactiveGenerator/ReactiveGenerator.cs +++ b/ReactiveGenerator/ReactiveGenerator.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using System.Linq; using System.Text; using Microsoft.CodeAnalysis; @@ -143,14 +144,14 @@ private static (INamedTypeSymbol Type, Location Location)? GetClassInfo(Generato if (context.Node is not PropertyDeclarationSyntax propertyDeclaration) return null; + // Get the symbol for the property var symbol = context.SemanticModel.GetDeclaredSymbol(propertyDeclaration) as IPropertySymbol; - if (symbol == null) + if (symbol is null) return null; + // Check property-level attributes for [Reactive] or [IgnoreReactive] bool hasReactiveAttribute = false; bool hasIgnoreAttribute = false; - - // Check property attributes foreach (var attributeList in propertyDeclaration.AttributeLists) { foreach (var attribute in attributeList.Attributes) @@ -163,19 +164,30 @@ private static (INamedTypeSymbol Type, Location Location)? GetClassInfo(Generato } } + // Check if containing type is "reactive" var containingType = symbol.ContainingType; - // Check if containing type should be reactive bool classHasReactiveAttribute = IsTypeReactive(containingType); - // Check if property has an implementation + // Check if user code has a non-trivial implementation + // (block body or expression body with real logic) bool hasImplementation = propertyDeclaration.AccessorList?.Accessors.Any( - a => a.Body != null || a.ExpressionBody != null) ?? false; + a => a.Body != null || a.ExpressionBody != null + ) ?? false; + + // If it's only "get => field" / "set => field = value" logic, treat it as no real user implementation + if (hasImplementation && IsTrivialFieldImplementation(propertyDeclaration)) + { + hasImplementation = false; + } - // Return property info if it either: - // 1. Has [Reactive] attribute directly - // 2. Is in a class (or base class) with [Reactive] attribute and doesn't have [IgnoreReactive] - // 3. Has no implementation yet - if ((hasReactiveAttribute || (classHasReactiveAttribute && !hasIgnoreAttribute)) && !hasImplementation) + // Decide if we should generate code + // We do so if: + // 1) The property or class is [Reactive], + // 2) There's no [IgnoreReactive], + // 3) The property doesn't already have a non-trivial implementation + if ((hasReactiveAttribute || (classHasReactiveAttribute && !hasIgnoreAttribute)) && + !hasIgnoreAttribute && + !hasImplementation) { return new PropertyInfo(symbol, hasReactiveAttribute, hasIgnoreAttribute, hasImplementation); } @@ -183,6 +195,70 @@ private static (INamedTypeSymbol Type, Location Location)? GetClassInfo(Generato return null; } + private static bool IsTrivialFieldImplementation(PropertyDeclarationSyntax propertyDeclaration) + { + if (propertyDeclaration.AccessorList is null) + return false; + + foreach (var accessor in propertyDeclaration.AccessorList.Accessors) + { + // If there's a block body { ... }, it's definitely not trivial + if (accessor.Body != null) + return false; + + // Check if it's an expression-bodied accessor + // like `get => field;`, `set => field = value;` + if (accessor.ExpressionBody != null) + { + var exprText = accessor.ExpressionBody.Expression.ToString().Trim(); + + if (accessor.Keyword.IsKind(SyntaxKind.GetKeyword)) + { + // Allowed minimal forms: + // - "field" + // - "field ?? something" + // You can expand as you like (e.g. "field ?? string.Empty") + if (!IsAllowedGetExpression(exprText)) + return false; + } + else if (accessor.Keyword.IsKind(SyntaxKind.SetKeyword)) + { + // Allowed minimal form: + // - "field = value" + // Possibly "field = value ?? something" if you wanted to allow that + if (!IsAllowedSetExpression(exprText)) + return false; + } + } + } + + // If we never returned false, it means all accessors are trivial "field" usage + return true; + } + + private static bool IsAllowedGetExpression(string expr) + { + // For example: + // "field" + // "field ?? string.Empty" + // "field ?? \"\"" + // or anything else you want to treat as "trivial" + if (expr == "field") + return true; + + if (expr.StartsWith("field ??", StringComparison.Ordinal)) + return true; + + return false; + } + + private static bool IsAllowedSetExpression(string expr) + { + // For instance, "field = value" + // If you want to allow "field = value ?? something", add logic + return expr == "field = value"; + } + private static bool InheritsFromReactiveObject(INamedTypeSymbol typeSymbol) { var current = typeSymbol; From 39b07686147216ab2d98b6e9c6225d7145ca1138 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wies=C5=82aw=20S=CC=8Colte=CC=81s?= Date: Wed, 25 Dec 2024 19:28:48 +0100 Subject: [PATCH 06/10] Update tests --- ...ect_ThenNoDoubleINPCInDerived.verified.txt | 51 +++ ...ctive_ThenDerivedIgnoresItToo.verified.txt | 89 ++++++ ...tive_ThenNoExtraINPCInDerived.verified.txt | 61 ++++ ...ass_ThenNoDoubleINPCInDerived.verified.txt | 89 ++++++ ...rTests.ClassInGlobalNamespace.verified.txt | 56 ---- ...s.ClassWithAbstractProperties.verified.txt | 56 ---- ...thCustomAccessorAccessibility.verified.txt | 70 ----- ...mentationAndReactiveAttribute.verified.txt | 25 -- ...ferentPropertyAccessibilities.verified.txt | 98 ------ ...plicitInterfaceImplementation.verified.txt | 56 ---- ...ithExpressionBodiedProperties.verified.txt | 56 ---- ...straintsAndNullableProperties.verified.txt | 70 ----- ...ssWithIgnoreReactiveAttribute.verified.txt | 56 ---- ...eratorTests.ClassWithIndexers.verified.txt | 56 ---- ...ests.ClassWithInitOnlySetters.verified.txt | 70 ----- ...WithMultipleInheritanceLevels.verified.txt | 31 -- ...Tests.ClassWithNestedGenerics.verified.txt | 70 ----- ...torTests.ClassWithNestedTypes.verified.txt | 62 ---- ...s.ClassWithNullableProperties.verified.txt | 70 ----- ...WithPropertyAccessorModifiers.verified.txt | 98 ------ ...assWithPropertyImplementation.verified.txt | 56 ---- ...AttributeInDifferentNamespace.verified.txt | 124 -------- ...s.ClassWithReadOnlyProperties.verified.txt | 62 ---- ...sts.ClassWithStaticProperties.verified.txt | 70 ----- ...ests.ClassWithTupleProperties.verified.txt | 70 ----- ...ts.ClassWithVirtualProperties.verified.txt | 70 ----- ...s.GenericClassWithConstraints.verified.txt | 70 ----- ...GenericPropertyImplementation.verified.txt | 53 ---- ...enericPropertyWithConstraints.verified.txt | 53 ---- ...opertyWithCustomAccessibility.verified.txt | 67 ---- ...GenericPropertyWithInitSetter.verified.txt | 67 ---- ...rtyWithMultipleTypeParameters.verified.txt | 67 ---- ...enericPropertyWithNestedTypes.verified.txt | 67 ---- ...nericPropertyWithNullableType.verified.txt | 53 ---- ...ricPropertyWithReadOnlyAccess.verified.txt | 59 ---- ...ts.InheritedReactiveAttribute.verified.txt | 46 +-- ...ceWithMixedReactiveAttributes.verified.txt | 46 +-- ...ClassesWithReactiveProperties.verified.txt | 62 ---- ...ultipleClassesWithInheritance.verified.txt | 31 -- ...ts.NestedClassWithInheritance.verified.txt | 34 -- ...hCustomPropertyImplementation.verified.txt | 62 ---- ...sWithDifferentAccessModifiers.verified.txt | 295 ------------------ ...ClassesWithGenericConstraints.verified.txt | 90 ------ ...sWithInheritanceAndInterfaces.verified.txt | 34 -- ...ClassesWithInitOnlyProperties.verified.txt | 76 ----- ...lassesWithMixedReactiveScopes.verified.txt | 65 ---- ...sWithStaticAndInstanceMembers.verified.txt | 76 ----- ...teClassWithReactiveProperties.verified.txt | 132 -------- ...pleClassWithReactiveAttribute.verified.txt | 56 ---- ...eratorTests.UseLegacyModeTest.verified.txt | 58 ---- 50 files changed, 336 insertions(+), 3125 deletions(-) create mode 100644 ReactiveGenerator.Tests/Snapshots/CrossAssemblyTests.ExternalBaseDerivedFromReactiveObject_ThenNoDoubleINPCInDerived.verified.txt create mode 100644 ReactiveGenerator.Tests/Snapshots/CrossAssemblyTests.ExternalBaseHasIgnoreReactive_ThenDerivedIgnoresItToo.verified.txt create mode 100644 ReactiveGenerator.Tests/Snapshots/CrossAssemblyTests.ExternalBaseHasPropertyLevelReactive_ThenNoExtraINPCInDerived.verified.txt create mode 100644 ReactiveGenerator.Tests/Snapshots/CrossAssemblyTests.ExternalBaseHasReactiveClass_ThenNoDoubleINPCInDerived.verified.txt diff --git a/ReactiveGenerator.Tests/Snapshots/CrossAssemblyTests.ExternalBaseDerivedFromReactiveObject_ThenNoDoubleINPCInDerived.verified.txt b/ReactiveGenerator.Tests/Snapshots/CrossAssemblyTests.ExternalBaseDerivedFromReactiveObject_ThenNoDoubleINPCInDerived.verified.txt new file mode 100644 index 0000000..51b7470 --- /dev/null +++ b/ReactiveGenerator.Tests/Snapshots/CrossAssemblyTests.ExternalBaseDerivedFromReactiveObject_ThenNoDoubleINPCInDerived.verified.txt @@ -0,0 +1,51 @@ +{ + Sources: [ + { + FileName: IgnoreReactiveAttribute.g.cs, + Source: +using System; + +[AttributeUsage(AttributeTargets.Property, Inherited = false, AllowMultiple = false)] +sealed class IgnoreReactiveAttribute : Attribute +{ + public IgnoreReactiveAttribute() { } +} + }, + { + FileName: MainLib.ChildViewModel.ReactiveProperties.g.cs, + Source: +// +#nullable enable + +using ReactiveUI; + +namespace MainLib +{ + /// + /// A partial class implementation for MainLib.ChildViewModel. + /// + public partial class ChildViewModel + { + public partial int AnotherProp + { + get => field; + set => this.RaiseAndSetIfChanged(ref field, value); + } + } +} + + }, + { + FileName: ReactiveAttribute.g.cs, + Source: +using System; + +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = false, AllowMultiple = false)] +sealed class ReactiveAttribute : Attribute +{ + public ReactiveAttribute() { } +} + } + ], + Diagnostics: null +} \ No newline at end of file diff --git a/ReactiveGenerator.Tests/Snapshots/CrossAssemblyTests.ExternalBaseHasIgnoreReactive_ThenDerivedIgnoresItToo.verified.txt b/ReactiveGenerator.Tests/Snapshots/CrossAssemblyTests.ExternalBaseHasIgnoreReactive_ThenDerivedIgnoresItToo.verified.txt new file mode 100644 index 0000000..4997f24 --- /dev/null +++ b/ReactiveGenerator.Tests/Snapshots/CrossAssemblyTests.ExternalBaseHasIgnoreReactive_ThenDerivedIgnoresItToo.verified.txt @@ -0,0 +1,89 @@ +{ + Sources: [ + { + FileName: ExternalLib.BaseWithIgnore.INPC.g.cs, + Source: +// +#nullable enable + +using System.ComponentModel; +using System.Runtime.CompilerServices; + +namespace ExternalLib +{ + public partial class BaseWithIgnore : INotifyPropertyChanged + { + public event PropertyChangedEventHandler? PropertyChanged; + + protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null) + { + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); + } + + protected virtual void OnPropertyChanged(PropertyChangedEventArgs args) + { + PropertyChanged?.Invoke(this, args); + } + } +} + + }, + { + FileName: IgnoreReactiveAttribute.g.cs, + Source: +using System; + +[AttributeUsage(AttributeTargets.Property, Inherited = false, AllowMultiple = false)] +sealed class IgnoreReactiveAttribute : Attribute +{ + public IgnoreReactiveAttribute() { } +} + }, + { + FileName: MainLib.DerivedIgnore.ReactiveProperties.g.cs, + Source: +// +#nullable enable + +using System.ComponentModel; +using System.Runtime.CompilerServices; + +namespace MainLib +{ + /// + /// A partial class implementation for MainLib.DerivedIgnore. + /// + public partial class DerivedIgnore + { + private static readonly PropertyChangedEventArgs _extraPropChangedEventArgs = new PropertyChangedEventArgs(nameof(ExtraProp)); + + public partial string ExtraProp + { + get => field; + set + { + if (!Equals(field, value)) + { + field = value; + OnPropertyChanged(_extraPropChangedEventArgs); + } + } + } + } +} + + }, + { + FileName: ReactiveAttribute.g.cs, + Source: +using System; + +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = false, AllowMultiple = false)] +sealed class ReactiveAttribute : Attribute +{ + public ReactiveAttribute() { } +} + } + ], + Diagnostics: null +} \ No newline at end of file diff --git a/ReactiveGenerator.Tests/Snapshots/CrossAssemblyTests.ExternalBaseHasPropertyLevelReactive_ThenNoExtraINPCInDerived.verified.txt b/ReactiveGenerator.Tests/Snapshots/CrossAssemblyTests.ExternalBaseHasPropertyLevelReactive_ThenNoExtraINPCInDerived.verified.txt new file mode 100644 index 0000000..98e5f5a --- /dev/null +++ b/ReactiveGenerator.Tests/Snapshots/CrossAssemblyTests.ExternalBaseHasPropertyLevelReactive_ThenNoExtraINPCInDerived.verified.txt @@ -0,0 +1,61 @@ +{ + Sources: [ + { + FileName: IgnoreReactiveAttribute.g.cs, + Source: +using System; + +[AttributeUsage(AttributeTargets.Property, Inherited = false, AllowMultiple = false)] +sealed class IgnoreReactiveAttribute : Attribute +{ + public IgnoreReactiveAttribute() { } +} + }, + { + FileName: MainLib.LocalDerived.ReactiveProperties.g.cs, + Source: +// +#nullable enable + +using System.ComponentModel; +using System.Runtime.CompilerServices; + +namespace MainLib +{ + /// + /// A partial class implementation for MainLib.LocalDerived. + /// + public partial class LocalDerived + { + private static readonly PropertyChangedEventArgs _localReactivePropChangedEventArgs = new PropertyChangedEventArgs(nameof(LocalReactiveProp)); + + public partial int LocalReactiveProp + { + get => field; + set + { + if (!Equals(field, value)) + { + field = value; + OnPropertyChanged(_localReactivePropChangedEventArgs); + } + } + } + } +} + + }, + { + FileName: ReactiveAttribute.g.cs, + Source: +using System; + +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = false, AllowMultiple = false)] +sealed class ReactiveAttribute : Attribute +{ + public ReactiveAttribute() { } +} + } + ], + Diagnostics: null +} \ No newline at end of file diff --git a/ReactiveGenerator.Tests/Snapshots/CrossAssemblyTests.ExternalBaseHasReactiveClass_ThenNoDoubleINPCInDerived.verified.txt b/ReactiveGenerator.Tests/Snapshots/CrossAssemblyTests.ExternalBaseHasReactiveClass_ThenNoDoubleINPCInDerived.verified.txt new file mode 100644 index 0000000..83aff6d --- /dev/null +++ b/ReactiveGenerator.Tests/Snapshots/CrossAssemblyTests.ExternalBaseHasReactiveClass_ThenNoDoubleINPCInDerived.verified.txt @@ -0,0 +1,89 @@ +{ + Sources: [ + { + FileName: ExternalLib.ExternalBase.INPC.g.cs, + Source: +// +#nullable enable + +using System.ComponentModel; +using System.Runtime.CompilerServices; + +namespace ExternalLib +{ + public partial class ExternalBase : INotifyPropertyChanged + { + public event PropertyChangedEventHandler? PropertyChanged; + + protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null) + { + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); + } + + protected virtual void OnPropertyChanged(PropertyChangedEventArgs args) + { + PropertyChanged?.Invoke(this, args); + } + } +} + + }, + { + FileName: IgnoreReactiveAttribute.g.cs, + Source: +using System; + +[AttributeUsage(AttributeTargets.Property, Inherited = false, AllowMultiple = false)] +sealed class IgnoreReactiveAttribute : Attribute +{ + public IgnoreReactiveAttribute() { } +} + }, + { + FileName: MainLib.DerivedClass.ReactiveProperties.g.cs, + Source: +// +#nullable enable + +using System.ComponentModel; +using System.Runtime.CompilerServices; + +namespace MainLib +{ + /// + /// A partial class implementation for MainLib.DerivedClass. + /// + public partial class DerivedClass + { + private static readonly PropertyChangedEventArgs _localPropChangedEventArgs = new PropertyChangedEventArgs(nameof(LocalProp)); + + public partial int LocalProp + { + get => field; + set + { + if (!Equals(field, value)) + { + field = value; + OnPropertyChanged(_localPropChangedEventArgs); + } + } + } + } +} + + }, + { + FileName: ReactiveAttribute.g.cs, + Source: +using System; + +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = false, AllowMultiple = false)] +sealed class ReactiveAttribute : Attribute +{ + public ReactiveAttribute() { } +} + } + ], + Diagnostics: null +} \ No newline at end of file diff --git a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassInGlobalNamespace.verified.txt b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassInGlobalNamespace.verified.txt index e28131e..4ce9ee1 100644 --- a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassInGlobalNamespace.verified.txt +++ b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassInGlobalNamespace.verified.txt @@ -1,61 +1,5 @@ { Sources: [ - { - FileName: GlobalClass.INPC.g.cs, - Source: -// -#nullable enable - -using System.ComponentModel; -using System.Runtime.CompilerServices; - -public partial class GlobalClass : INotifyPropertyChanged -{ - public event PropertyChangedEventHandler? PropertyChanged; - - protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null) - { - PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); - } - - protected virtual void OnPropertyChanged(PropertyChangedEventArgs args) - { - PropertyChanged?.Invoke(this, args); - } -} - - }, - { - FileName: GlobalClass.ReactiveProperties.g.cs, - Source: -// -#nullable enable - -using System.ComponentModel; -using System.Runtime.CompilerServices; - -/// -/// A partial class implementation for GlobalClass. -/// -public partial class GlobalClass -{ - private static readonly PropertyChangedEventArgs _nameChangedEventArgs = new PropertyChangedEventArgs(nameof(Name)); - - public partial string Name - { - get => field; - set - { - if (!Equals(field, value)) - { - field = value; - OnPropertyChanged(_nameChangedEventArgs); - } - } - } -} - - }, { FileName: IgnoreReactiveAttribute.g.cs, Source: diff --git a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithAbstractProperties.verified.txt b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithAbstractProperties.verified.txt index 7235aa7..4ce9ee1 100644 --- a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithAbstractProperties.verified.txt +++ b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithAbstractProperties.verified.txt @@ -21,62 +21,6 @@ sealed class ReactiveAttribute : Attribute { public ReactiveAttribute() { } } - }, - { - FileName: TestClass.INPC.g.cs, - Source: -// -#nullable enable - -using System.ComponentModel; -using System.Runtime.CompilerServices; - -public partial class TestClass : INotifyPropertyChanged -{ - public event PropertyChangedEventHandler? PropertyChanged; - - protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null) - { - PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); - } - - protected virtual void OnPropertyChanged(PropertyChangedEventArgs args) - { - PropertyChanged?.Invoke(this, args); - } -} - - }, - { - FileName: TestClass.ReactiveProperties.g.cs, - Source: -// -#nullable enable - -using System.ComponentModel; -using System.Runtime.CompilerServices; - -/// -/// A partial class implementation for TestClass. -/// -public partial class TestClass -{ - private static readonly PropertyChangedEventArgs _concretePropChangedEventArgs = new PropertyChangedEventArgs(nameof(ConcreteProp)); - - public partial string ConcreteProp - { - get => field; - set - { - if (!Equals(field, value)) - { - field = value; - OnPropertyChanged(_concretePropChangedEventArgs); - } - } - } -} - } ], Diagnostics: null diff --git a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithCustomAccessorAccessibility.verified.txt b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithCustomAccessorAccessibility.verified.txt index 613e822..4ce9ee1 100644 --- a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithCustomAccessorAccessibility.verified.txt +++ b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithCustomAccessorAccessibility.verified.txt @@ -21,76 +21,6 @@ sealed class ReactiveAttribute : Attribute { public ReactiveAttribute() { } } - }, - { - FileName: TestClass.INPC.g.cs, - Source: -// -#nullable enable - -using System.ComponentModel; -using System.Runtime.CompilerServices; - -public partial class TestClass : INotifyPropertyChanged -{ - public event PropertyChangedEventHandler? PropertyChanged; - - protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null) - { - PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); - } - - protected virtual void OnPropertyChanged(PropertyChangedEventArgs args) - { - PropertyChanged?.Invoke(this, args); - } -} - - }, - { - FileName: TestClass.ReactiveProperties.g.cs, - Source: -// -#nullable enable - -using System.ComponentModel; -using System.Runtime.CompilerServices; - -/// -/// A partial class implementation for TestClass. -/// -public partial class TestClass -{ - private static readonly PropertyChangedEventArgs _nameChangedEventArgs = new PropertyChangedEventArgs(nameof(Name)); - private static readonly PropertyChangedEventArgs _idChangedEventArgs = new PropertyChangedEventArgs(nameof(Id)); - - public partial string Name - { - get => field; - private set - { - if (!Equals(field, value)) - { - field = value; - OnPropertyChanged(_nameChangedEventArgs); - } - } - } - - protected partial string Id - { - private get => field; - set - { - if (!Equals(field, value)) - { - field = value; - OnPropertyChanged(_idChangedEventArgs); - } - } - } -} - } ], Diagnostics: null diff --git a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithCustomPropertyImplementationAndReactiveAttribute.verified.txt b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithCustomPropertyImplementationAndReactiveAttribute.verified.txt index 014db9c..4ce9ee1 100644 --- a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithCustomPropertyImplementationAndReactiveAttribute.verified.txt +++ b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithCustomPropertyImplementationAndReactiveAttribute.verified.txt @@ -21,31 +21,6 @@ sealed class ReactiveAttribute : Attribute { public ReactiveAttribute() { } } - }, - { - FileName: TestClass.INPC.g.cs, - Source: -// -#nullable enable - -using System.ComponentModel; -using System.Runtime.CompilerServices; - -public partial class TestClass : INotifyPropertyChanged -{ - public event PropertyChangedEventHandler? PropertyChanged; - - protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null) - { - PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); - } - - protected virtual void OnPropertyChanged(PropertyChangedEventArgs args) - { - PropertyChanged?.Invoke(this, args); - } -} - } ], Diagnostics: null diff --git a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithDifferentPropertyAccessibilities.verified.txt b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithDifferentPropertyAccessibilities.verified.txt index 7c82631..4ce9ee1 100644 --- a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithDifferentPropertyAccessibilities.verified.txt +++ b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithDifferentPropertyAccessibilities.verified.txt @@ -21,104 +21,6 @@ sealed class ReactiveAttribute : Attribute { public ReactiveAttribute() { } } - }, - { - FileName: TestClass.INPC.g.cs, - Source: -// -#nullable enable - -using System.ComponentModel; -using System.Runtime.CompilerServices; - -public partial class TestClass : INotifyPropertyChanged -{ - public event PropertyChangedEventHandler? PropertyChanged; - - protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null) - { - PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); - } - - protected virtual void OnPropertyChanged(PropertyChangedEventArgs args) - { - PropertyChanged?.Invoke(this, args); - } -} - - }, - { - FileName: TestClass.ReactiveProperties.g.cs, - Source: -// -#nullable enable - -using System.ComponentModel; -using System.Runtime.CompilerServices; - -/// -/// A partial class implementation for TestClass. -/// -public partial class TestClass -{ - private static readonly PropertyChangedEventArgs _publicPropChangedEventArgs = new PropertyChangedEventArgs(nameof(PublicProp)); - private static readonly PropertyChangedEventArgs _protectedPropChangedEventArgs = new PropertyChangedEventArgs(nameof(ProtectedProp)); - private static readonly PropertyChangedEventArgs _internalPropChangedEventArgs = new PropertyChangedEventArgs(nameof(InternalProp)); - private static readonly PropertyChangedEventArgs _privatePropChangedEventArgs = new PropertyChangedEventArgs(nameof(PrivateProp)); - - public partial string PublicProp - { - get => field; - set - { - if (!Equals(field, value)) - { - field = value; - OnPropertyChanged(_publicPropChangedEventArgs); - } - } - } - - protected partial string ProtectedProp - { - get => field; - set - { - if (!Equals(field, value)) - { - field = value; - OnPropertyChanged(_protectedPropChangedEventArgs); - } - } - } - - internal partial string InternalProp - { - get => field; - set - { - if (!Equals(field, value)) - { - field = value; - OnPropertyChanged(_internalPropChangedEventArgs); - } - } - } - - private partial string PrivateProp - { - get => field; - set - { - if (!Equals(field, value)) - { - field = value; - OnPropertyChanged(_privatePropChangedEventArgs); - } - } - } -} - } ], Diagnostics: null diff --git a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithExplicitInterfaceImplementation.verified.txt b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithExplicitInterfaceImplementation.verified.txt index a4005c7..4ce9ee1 100644 --- a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithExplicitInterfaceImplementation.verified.txt +++ b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithExplicitInterfaceImplementation.verified.txt @@ -21,62 +21,6 @@ sealed class ReactiveAttribute : Attribute { public ReactiveAttribute() { } } - }, - { - FileName: TestClass.INPC.g.cs, - Source: -// -#nullable enable - -using System.ComponentModel; -using System.Runtime.CompilerServices; - -public partial class TestClass : INotifyPropertyChanged -{ - public event PropertyChangedEventHandler? PropertyChanged; - - protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null) - { - PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); - } - - protected virtual void OnPropertyChanged(PropertyChangedEventArgs args) - { - PropertyChanged?.Invoke(this, args); - } -} - - }, - { - FileName: TestClass.ReactiveProperties.g.cs, - Source: -// -#nullable enable - -using System.ComponentModel; -using System.Runtime.CompilerServices; - -/// -/// A partial class implementation for TestClass. -/// -public partial class TestClass -{ - private static readonly PropertyChangedEventArgs _publicNameChangedEventArgs = new PropertyChangedEventArgs(nameof(PublicName)); - - public partial string PublicName - { - get => field; - set - { - if (!Equals(field, value)) - { - field = value; - OnPropertyChanged(_publicNameChangedEventArgs); - } - } - } -} - } ], Diagnostics: null diff --git a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithExpressionBodiedProperties.verified.txt b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithExpressionBodiedProperties.verified.txt index f90ffb6..4ce9ee1 100644 --- a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithExpressionBodiedProperties.verified.txt +++ b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithExpressionBodiedProperties.verified.txt @@ -21,62 +21,6 @@ sealed class ReactiveAttribute : Attribute { public ReactiveAttribute() { } } - }, - { - FileName: TestClass.INPC.g.cs, - Source: -// -#nullable enable - -using System.ComponentModel; -using System.Runtime.CompilerServices; - -public partial class TestClass : INotifyPropertyChanged -{ - public event PropertyChangedEventHandler? PropertyChanged; - - protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null) - { - PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); - } - - protected virtual void OnPropertyChanged(PropertyChangedEventArgs args) - { - PropertyChanged?.Invoke(this, args); - } -} - - }, - { - FileName: TestClass.ReactiveProperties.g.cs, - Source: -// -#nullable enable - -using System.ComponentModel; -using System.Runtime.CompilerServices; - -/// -/// A partial class implementation for TestClass. -/// -public partial class TestClass -{ - private static readonly PropertyChangedEventArgs _editableNameChangedEventArgs = new PropertyChangedEventArgs(nameof(EditableName)); - - public partial string EditableName - { - get => field; - set - { - if (!Equals(field, value)) - { - field = value; - OnPropertyChanged(_editableNameChangedEventArgs); - } - } - } -} - } ], Diagnostics: null diff --git a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithGenericConstraintsAndNullableProperties.verified.txt b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithGenericConstraintsAndNullableProperties.verified.txt index c7ac2d8..4ce9ee1 100644 --- a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithGenericConstraintsAndNullableProperties.verified.txt +++ b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithGenericConstraintsAndNullableProperties.verified.txt @@ -21,76 +21,6 @@ sealed class ReactiveAttribute : Attribute { public ReactiveAttribute() { } } - }, - { - FileName: TestClass.INPC.g.cs, - Source: -// -#nullable enable - -using System.ComponentModel; -using System.Runtime.CompilerServices; - -public partial class TestClass : INotifyPropertyChanged where T : class, IDisposable where U : struct, IComparable -{ - public event PropertyChangedEventHandler? PropertyChanged; - - protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null) - { - PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); - } - - protected virtual void OnPropertyChanged(PropertyChangedEventArgs args) - { - PropertyChanged?.Invoke(this, args); - } -} - - }, - { - FileName: TestClass.ReactiveProperties.g.cs, - Source: -// -#nullable enable - -using System.ComponentModel; -using System.Runtime.CompilerServices; - -/// -/// A partial class implementation for TestClass{T, U}. -/// -public partial class TestClass where T : class, IDisposable where U : struct, IComparable -{ - private static readonly PropertyChangedEventArgs _nullableRefChangedEventArgs = new PropertyChangedEventArgs(nameof(NullableRef)); - private static readonly PropertyChangedEventArgs _nullableStructChangedEventArgs = new PropertyChangedEventArgs(nameof(NullableStruct)); - - public partial T? NullableRef - { - get => field; - set - { - if (!Equals(field, value)) - { - field = value; - OnPropertyChanged(_nullableRefChangedEventArgs); - } - } - } - - public partial U? NullableStruct - { - get => field; - set - { - if (!Equals(field, value)) - { - field = value; - OnPropertyChanged(_nullableStructChangedEventArgs); - } - } - } -} - } ], Diagnostics: null diff --git a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithIgnoreReactiveAttribute.verified.txt b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithIgnoreReactiveAttribute.verified.txt index d959681..4ce9ee1 100644 --- a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithIgnoreReactiveAttribute.verified.txt +++ b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithIgnoreReactiveAttribute.verified.txt @@ -21,62 +21,6 @@ sealed class ReactiveAttribute : Attribute { public ReactiveAttribute() { } } - }, - { - FileName: TestClass.INPC.g.cs, - Source: -// -#nullable enable - -using System.ComponentModel; -using System.Runtime.CompilerServices; - -public partial class TestClass : INotifyPropertyChanged -{ - public event PropertyChangedEventHandler? PropertyChanged; - - protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null) - { - PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); - } - - protected virtual void OnPropertyChanged(PropertyChangedEventArgs args) - { - PropertyChanged?.Invoke(this, args); - } -} - - }, - { - FileName: TestClass.ReactiveProperties.g.cs, - Source: -// -#nullable enable - -using System.ComponentModel; -using System.Runtime.CompilerServices; - -/// -/// A partial class implementation for TestClass. -/// -public partial class TestClass -{ - private static readonly PropertyChangedEventArgs _includedChangedEventArgs = new PropertyChangedEventArgs(nameof(Included)); - - public partial string Included - { - get => field; - set - { - if (!Equals(field, value)) - { - field = value; - OnPropertyChanged(_includedChangedEventArgs); - } - } - } -} - } ], Diagnostics: null diff --git a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithIndexers.verified.txt b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithIndexers.verified.txt index 09fde30..4ce9ee1 100644 --- a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithIndexers.verified.txt +++ b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithIndexers.verified.txt @@ -21,62 +21,6 @@ sealed class ReactiveAttribute : Attribute { public ReactiveAttribute() { } } - }, - { - FileName: TestClass.INPC.g.cs, - Source: -// -#nullable enable - -using System.ComponentModel; -using System.Runtime.CompilerServices; - -public partial class TestClass : INotifyPropertyChanged -{ - public event PropertyChangedEventHandler? PropertyChanged; - - protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null) - { - PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); - } - - protected virtual void OnPropertyChanged(PropertyChangedEventArgs args) - { - PropertyChanged?.Invoke(this, args); - } -} - - }, - { - FileName: TestClass.ReactiveProperties.g.cs, - Source: -// -#nullable enable - -using System.ComponentModel; -using System.Runtime.CompilerServices; - -/// -/// A partial class implementation for TestClass. -/// -public partial class TestClass -{ - private static readonly PropertyChangedEventArgs _regularPropChangedEventArgs = new PropertyChangedEventArgs(nameof(RegularProp)); - - public partial string RegularProp - { - get => field; - set - { - if (!Equals(field, value)) - { - field = value; - OnPropertyChanged(_regularPropChangedEventArgs); - } - } - } -} - } ], Diagnostics: null diff --git a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithInitOnlySetters.verified.txt b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithInitOnlySetters.verified.txt index 910b9da..4ce9ee1 100644 --- a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithInitOnlySetters.verified.txt +++ b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithInitOnlySetters.verified.txt @@ -21,76 +21,6 @@ sealed class ReactiveAttribute : Attribute { public ReactiveAttribute() { } } - }, - { - FileName: TestClass.INPC.g.cs, - Source: -// -#nullable enable - -using System.ComponentModel; -using System.Runtime.CompilerServices; - -public partial class TestClass : INotifyPropertyChanged -{ - public event PropertyChangedEventHandler? PropertyChanged; - - protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null) - { - PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); - } - - protected virtual void OnPropertyChanged(PropertyChangedEventArgs args) - { - PropertyChanged?.Invoke(this, args); - } -} - - }, - { - FileName: TestClass.ReactiveProperties.g.cs, - Source: -// -#nullable enable - -using System.ComponentModel; -using System.Runtime.CompilerServices; - -/// -/// A partial class implementation for TestClass. -/// -public partial class TestClass -{ - private static readonly PropertyChangedEventArgs _initOnlyPropChangedEventArgs = new PropertyChangedEventArgs(nameof(InitOnlyProp)); - private static readonly PropertyChangedEventArgs _regularPropChangedEventArgs = new PropertyChangedEventArgs(nameof(RegularProp)); - - public partial string InitOnlyProp - { - get => field; - set - { - if (!Equals(field, value)) - { - field = value; - OnPropertyChanged(_initOnlyPropChangedEventArgs); - } - } - } - - public partial string RegularProp - { - get => field; - set - { - if (!Equals(field, value)) - { - field = value; - OnPropertyChanged(_regularPropChangedEventArgs); - } - } - } -} - } ], Diagnostics: null diff --git a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithMultipleInheritanceLevels.verified.txt b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithMultipleInheritanceLevels.verified.txt index ba6007b..ed47ada 100644 --- a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithMultipleInheritanceLevels.verified.txt +++ b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithMultipleInheritanceLevels.verified.txt @@ -66,37 +66,6 @@ public partial class Parent : INotifyPropertyChanged } } - }, - { - FileName: Parent.ReactiveProperties.g.cs, - Source: -// -#nullable enable - -using System.ComponentModel; -using System.Runtime.CompilerServices; - -/// -/// A partial class implementation for Parent. -/// -public partial class Parent -{ - private static readonly PropertyChangedEventArgs _parentPropChangedEventArgs = new PropertyChangedEventArgs(nameof(ParentProp)); - - public partial string ParentProp - { - get => field; - set - { - if (!Equals(field, value)) - { - field = value; - OnPropertyChanged(_parentPropChangedEventArgs); - } - } - } -} - }, { FileName: ReactiveAttribute.g.cs, diff --git a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithNestedGenerics.verified.txt b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithNestedGenerics.verified.txt index 3c547cb..4ce9ee1 100644 --- a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithNestedGenerics.verified.txt +++ b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithNestedGenerics.verified.txt @@ -21,76 +21,6 @@ sealed class ReactiveAttribute : Attribute { public ReactiveAttribute() { } } - }, - { - FileName: TestClass.INPC.g.cs, - Source: -// -#nullable enable - -using System.ComponentModel; -using System.Runtime.CompilerServices; - -public partial class TestClass : INotifyPropertyChanged where T : class -{ - public event PropertyChangedEventHandler? PropertyChanged; - - protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null) - { - PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); - } - - protected virtual void OnPropertyChanged(PropertyChangedEventArgs args) - { - PropertyChanged?.Invoke(this, args); - } -} - - }, - { - FileName: TestClass.ReactiveProperties.g.cs, - Source: -// -#nullable enable - -using System.ComponentModel; -using System.Runtime.CompilerServices; - -/// -/// A partial class implementation for TestClass{T}. -/// -public partial class TestClass where T : class -{ - private static readonly PropertyChangedEventArgs _complexPropChangedEventArgs = new PropertyChangedEventArgs(nameof(ComplexProp)); - private static readonly PropertyChangedEventArgs _nestedPropChangedEventArgs = new PropertyChangedEventArgs(nameof(NestedProp)); - - public partial List> ComplexProp - { - get => field; - set - { - if (!Equals(field, value)) - { - field = value; - OnPropertyChanged(_complexPropChangedEventArgs); - } - } - } - - public partial Dictionary> NestedProp - { - get => field; - set - { - if (!Equals(field, value)) - { - field = value; - OnPropertyChanged(_nestedPropChangedEventArgs); - } - } - } -} - } ], Diagnostics: null diff --git a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithNestedTypes.verified.txt b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithNestedTypes.verified.txt index 10f445c..4ce9ee1 100644 --- a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithNestedTypes.verified.txt +++ b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithNestedTypes.verified.txt @@ -10,68 +10,6 @@ sealed class IgnoreReactiveAttribute : Attribute { public IgnoreReactiveAttribute() { } } - }, - { - FileName: OuterClass.InnerClass.INPC.g.cs, - Source: -// -#nullable enable - -using System.ComponentModel; -using System.Runtime.CompilerServices; - -public partial class OuterClass -{ - public partial class InnerClass : INotifyPropertyChanged - { - public event PropertyChangedEventHandler? PropertyChanged; - - protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null) - { - PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); - } - - protected virtual void OnPropertyChanged(PropertyChangedEventArgs args) - { - PropertyChanged?.Invoke(this, args); - } - } -} - - }, - { - FileName: OuterClass.InnerClass.ReactiveProperties.g.cs, - Source: -// -#nullable enable - -using System.ComponentModel; -using System.Runtime.CompilerServices; - -public partial class OuterClass -{ - /// - /// A partial class implementation for OuterClass.InnerClass. - /// - public partial class InnerClass - { - private static readonly PropertyChangedEventArgs _nameChangedEventArgs = new PropertyChangedEventArgs(nameof(Name)); - - public partial string Name - { - get => field; - set - { - if (!Equals(field, value)) - { - field = value; - OnPropertyChanged(_nameChangedEventArgs); - } - } - } - } -} - }, { FileName: ReactiveAttribute.g.cs, diff --git a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithNullableProperties.verified.txt b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithNullableProperties.verified.txt index b0b3bba..4ce9ee1 100644 --- a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithNullableProperties.verified.txt +++ b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithNullableProperties.verified.txt @@ -21,76 +21,6 @@ sealed class ReactiveAttribute : Attribute { public ReactiveAttribute() { } } - }, - { - FileName: TestClass.INPC.g.cs, - Source: -// -#nullable enable - -using System.ComponentModel; -using System.Runtime.CompilerServices; - -public partial class TestClass : INotifyPropertyChanged -{ - public event PropertyChangedEventHandler? PropertyChanged; - - protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null) - { - PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); - } - - protected virtual void OnPropertyChanged(PropertyChangedEventArgs args) - { - PropertyChanged?.Invoke(this, args); - } -} - - }, - { - FileName: TestClass.ReactiveProperties.g.cs, - Source: -// -#nullable enable - -using System.ComponentModel; -using System.Runtime.CompilerServices; - -/// -/// A partial class implementation for TestClass. -/// -public partial class TestClass -{ - private static readonly PropertyChangedEventArgs _nullableRefChangedEventArgs = new PropertyChangedEventArgs(nameof(NullableRef)); - private static readonly PropertyChangedEventArgs _nullableValueChangedEventArgs = new PropertyChangedEventArgs(nameof(NullableValue)); - - public partial string? NullableRef - { - get => field; - set - { - if (!Equals(field, value)) - { - field = value; - OnPropertyChanged(_nullableRefChangedEventArgs); - } - } - } - - public partial int? NullableValue - { - get => field; - set - { - if (!Equals(field, value)) - { - field = value; - OnPropertyChanged(_nullableValueChangedEventArgs); - } - } - } -} - } ], Diagnostics: null diff --git a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithPropertyAccessorModifiers.verified.txt b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithPropertyAccessorModifiers.verified.txt index c1a8b97..4ce9ee1 100644 --- a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithPropertyAccessorModifiers.verified.txt +++ b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithPropertyAccessorModifiers.verified.txt @@ -21,104 +21,6 @@ sealed class ReactiveAttribute : Attribute { public ReactiveAttribute() { } } - }, - { - FileName: TestClass.INPC.g.cs, - Source: -// -#nullable enable - -using System.ComponentModel; -using System.Runtime.CompilerServices; - -public partial class TestClass : INotifyPropertyChanged -{ - public event PropertyChangedEventHandler? PropertyChanged; - - protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null) - { - PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); - } - - protected virtual void OnPropertyChanged(PropertyChangedEventArgs args) - { - PropertyChanged?.Invoke(this, args); - } -} - - }, - { - FileName: TestClass.ReactiveProperties.g.cs, - Source: -// -#nullable enable - -using System.ComponentModel; -using System.Runtime.CompilerServices; - -/// -/// A partial class implementation for TestClass. -/// -public partial class TestClass -{ - private static readonly PropertyChangedEventArgs _propWithPrivateSetChangedEventArgs = new PropertyChangedEventArgs(nameof(PropWithPrivateSet)); - private static readonly PropertyChangedEventArgs _propWithProtectedGetChangedEventArgs = new PropertyChangedEventArgs(nameof(PropWithProtectedGet)); - private static readonly PropertyChangedEventArgs _propWithInternalSetChangedEventArgs = new PropertyChangedEventArgs(nameof(PropWithInternalSet)); - private static readonly PropertyChangedEventArgs _propWithProtectedInternalSetChangedEventArgs = new PropertyChangedEventArgs(nameof(PropWithProtectedInternalSet)); - - public partial string PropWithPrivateSet - { - get => field; - private set - { - if (!Equals(field, value)) - { - field = value; - OnPropertyChanged(_propWithPrivateSetChangedEventArgs); - } - } - } - - protected partial string PropWithProtectedGet - { - private get => field; - set - { - if (!Equals(field, value)) - { - field = value; - OnPropertyChanged(_propWithProtectedGetChangedEventArgs); - } - } - } - - internal partial string PropWithInternalSet - { - get => field; - set - { - if (!Equals(field, value)) - { - field = value; - OnPropertyChanged(_propWithInternalSetChangedEventArgs); - } - } - } - - public partial string PropWithProtectedInternalSet - { - get => field; - protected internal set - { - if (!Equals(field, value)) - { - field = value; - OnPropertyChanged(_propWithProtectedInternalSetChangedEventArgs); - } - } - } -} - } ], Diagnostics: null diff --git a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithPropertyImplementation.verified.txt b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithPropertyImplementation.verified.txt index bd92178..4ce9ee1 100644 --- a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithPropertyImplementation.verified.txt +++ b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithPropertyImplementation.verified.txt @@ -21,62 +21,6 @@ sealed class ReactiveAttribute : Attribute { public ReactiveAttribute() { } } - }, - { - FileName: TestClass.INPC.g.cs, - Source: -// -#nullable enable - -using System.ComponentModel; -using System.Runtime.CompilerServices; - -public partial class TestClass : INotifyPropertyChanged -{ - public event PropertyChangedEventHandler? PropertyChanged; - - protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null) - { - PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); - } - - protected virtual void OnPropertyChanged(PropertyChangedEventArgs args) - { - PropertyChanged?.Invoke(this, args); - } -} - - }, - { - FileName: TestClass.ReactiveProperties.g.cs, - Source: -// -#nullable enable - -using System.ComponentModel; -using System.Runtime.CompilerServices; - -/// -/// A partial class implementation for TestClass. -/// -public partial class TestClass -{ - private static readonly PropertyChangedEventArgs _notImplementedChangedEventArgs = new PropertyChangedEventArgs(nameof(NotImplemented)); - - public partial string NotImplemented - { - get => field; - set - { - if (!Equals(field, value)) - { - field = value; - OnPropertyChanged(_notImplementedChangedEventArgs); - } - } - } -} - } ], Diagnostics: null diff --git a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithReactiveAttributeInDifferentNamespace.verified.txt b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithReactiveAttributeInDifferentNamespace.verified.txt index 9480f70..4ce9ee1 100644 --- a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithReactiveAttributeInDifferentNamespace.verified.txt +++ b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithReactiveAttributeInDifferentNamespace.verified.txt @@ -1,67 +1,5 @@ { Sources: [ - { - FileName: First.TestClass.INPC.g.cs, - Source: -// -#nullable enable - -using System.ComponentModel; -using System.Runtime.CompilerServices; - -namespace First -{ - public partial class TestClass : INotifyPropertyChanged - { - public event PropertyChangedEventHandler? PropertyChanged; - - protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null) - { - PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); - } - - protected virtual void OnPropertyChanged(PropertyChangedEventArgs args) - { - PropertyChanged?.Invoke(this, args); - } - } -} - - }, - { - FileName: First.TestClass.ReactiveProperties.g.cs, - Source: -// -#nullable enable - -using System.ComponentModel; -using System.Runtime.CompilerServices; - -namespace First -{ - /// - /// A partial class implementation for First.TestClass. - /// - public partial class TestClass - { - private static readonly PropertyChangedEventArgs _nameChangedEventArgs = new PropertyChangedEventArgs(nameof(Name)); - - public partial string Name - { - get => field; - set - { - if (!Equals(field, value)) - { - field = value; - OnPropertyChanged(_nameChangedEventArgs); - } - } - } - } -} - - }, { FileName: IgnoreReactiveAttribute.g.cs, Source: @@ -83,68 +21,6 @@ sealed class ReactiveAttribute : Attribute { public ReactiveAttribute() { } } - }, - { - FileName: Second.TestClass.INPC.g.cs, - Source: -// -#nullable enable - -using System.ComponentModel; -using System.Runtime.CompilerServices; - -namespace Second -{ - public partial class TestClass : INotifyPropertyChanged - { - public event PropertyChangedEventHandler? PropertyChanged; - - protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null) - { - PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); - } - - protected virtual void OnPropertyChanged(PropertyChangedEventArgs args) - { - PropertyChanged?.Invoke(this, args); - } - } -} - - }, - { - FileName: Second.TestClass.ReactiveProperties.g.cs, - Source: -// -#nullable enable - -using System.ComponentModel; -using System.Runtime.CompilerServices; - -namespace Second -{ - /// - /// A partial class implementation for Second.TestClass. - /// - public partial class TestClass - { - private static readonly PropertyChangedEventArgs _nameChangedEventArgs = new PropertyChangedEventArgs(nameof(Name)); - - public partial string Name - { - get => field; - set - { - if (!Equals(field, value)) - { - field = value; - OnPropertyChanged(_nameChangedEventArgs); - } - } - } - } -} - } ], Diagnostics: null diff --git a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithReadOnlyProperties.verified.txt b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithReadOnlyProperties.verified.txt index 88a9934..4ce9ee1 100644 --- a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithReadOnlyProperties.verified.txt +++ b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithReadOnlyProperties.verified.txt @@ -21,68 +21,6 @@ sealed class ReactiveAttribute : Attribute { public ReactiveAttribute() { } } - }, - { - FileName: TestClass.INPC.g.cs, - Source: -// -#nullable enable - -using System.ComponentModel; -using System.Runtime.CompilerServices; - -public partial class TestClass : INotifyPropertyChanged -{ - public event PropertyChangedEventHandler? PropertyChanged; - - protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null) - { - PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); - } - - protected virtual void OnPropertyChanged(PropertyChangedEventArgs args) - { - PropertyChanged?.Invoke(this, args); - } -} - - }, - { - FileName: TestClass.ReactiveProperties.g.cs, - Source: -// -#nullable enable - -using System.ComponentModel; -using System.Runtime.CompilerServices; - -/// -/// A partial class implementation for TestClass. -/// -public partial class TestClass -{ - private static readonly PropertyChangedEventArgs _readOnlyChangedEventArgs = new PropertyChangedEventArgs(nameof(ReadOnly)); - private static readonly PropertyChangedEventArgs _readWriteChangedEventArgs = new PropertyChangedEventArgs(nameof(ReadWrite)); - - public partial string ReadOnly - { - get => field; - } - - public partial string ReadWrite - { - get => field; - set - { - if (!Equals(field, value)) - { - field = value; - OnPropertyChanged(_readWriteChangedEventArgs); - } - } - } -} - } ], Diagnostics: null diff --git a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithStaticProperties.verified.txt b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithStaticProperties.verified.txt index bae1230..4ce9ee1 100644 --- a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithStaticProperties.verified.txt +++ b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithStaticProperties.verified.txt @@ -21,76 +21,6 @@ sealed class ReactiveAttribute : Attribute { public ReactiveAttribute() { } } - }, - { - FileName: TestClass.INPC.g.cs, - Source: -// -#nullable enable - -using System.ComponentModel; -using System.Runtime.CompilerServices; - -public partial class TestClass : INotifyPropertyChanged -{ - public event PropertyChangedEventHandler? PropertyChanged; - - protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null) - { - PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); - } - - protected virtual void OnPropertyChanged(PropertyChangedEventArgs args) - { - PropertyChanged?.Invoke(this, args); - } -} - - }, - { - FileName: TestClass.ReactiveProperties.g.cs, - Source: -// -#nullable enable - -using System.ComponentModel; -using System.Runtime.CompilerServices; - -/// -/// A partial class implementation for TestClass. -/// -public partial class TestClass -{ - private static readonly PropertyChangedEventArgs _staticPropChangedEventArgs = new PropertyChangedEventArgs(nameof(StaticProp)); - private static readonly PropertyChangedEventArgs _instancePropChangedEventArgs = new PropertyChangedEventArgs(nameof(InstanceProp)); - - public partial string StaticProp - { - get => field; - set - { - if (!Equals(field, value)) - { - field = value; - OnPropertyChanged(_staticPropChangedEventArgs); - } - } - } - - public partial string InstanceProp - { - get => field; - set - { - if (!Equals(field, value)) - { - field = value; - OnPropertyChanged(_instancePropChangedEventArgs); - } - } - } -} - } ], Diagnostics: null diff --git a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithTupleProperties.verified.txt b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithTupleProperties.verified.txt index 186f410..4ce9ee1 100644 --- a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithTupleProperties.verified.txt +++ b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithTupleProperties.verified.txt @@ -21,76 +21,6 @@ sealed class ReactiveAttribute : Attribute { public ReactiveAttribute() { } } - }, - { - FileName: TestClass.INPC.g.cs, - Source: -// -#nullable enable - -using System.ComponentModel; -using System.Runtime.CompilerServices; - -public partial class TestClass : INotifyPropertyChanged -{ - public event PropertyChangedEventHandler? PropertyChanged; - - protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null) - { - PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); - } - - protected virtual void OnPropertyChanged(PropertyChangedEventArgs args) - { - PropertyChanged?.Invoke(this, args); - } -} - - }, - { - FileName: TestClass.ReactiveProperties.g.cs, - Source: -// -#nullable enable - -using System.ComponentModel; -using System.Runtime.CompilerServices; - -/// -/// A partial class implementation for TestClass. -/// -public partial class TestClass -{ - private static readonly PropertyChangedEventArgs _personInfoChangedEventArgs = new PropertyChangedEventArgs(nameof(PersonInfo)); - private static readonly PropertyChangedEventArgs _pointChangedEventArgs = new PropertyChangedEventArgs(nameof(Point)); - - public partial (string Name, int Age) PersonInfo - { - get => field; - set - { - if (!Equals(field, value)) - { - field = value; - OnPropertyChanged(_personInfoChangedEventArgs); - } - } - } - - public partial (int X, int Y, string Label) Point - { - get => field; - set - { - if (!Equals(field, value)) - { - field = value; - OnPropertyChanged(_pointChangedEventArgs); - } - } - } -} - } ], Diagnostics: null diff --git a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithVirtualProperties.verified.txt b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithVirtualProperties.verified.txt index 203f5cb..4ce9ee1 100644 --- a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithVirtualProperties.verified.txt +++ b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithVirtualProperties.verified.txt @@ -21,76 +21,6 @@ sealed class ReactiveAttribute : Attribute { public ReactiveAttribute() { } } - }, - { - FileName: TestClass.INPC.g.cs, - Source: -// -#nullable enable - -using System.ComponentModel; -using System.Runtime.CompilerServices; - -public partial class TestClass : INotifyPropertyChanged -{ - public event PropertyChangedEventHandler? PropertyChanged; - - protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null) - { - PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); - } - - protected virtual void OnPropertyChanged(PropertyChangedEventArgs args) - { - PropertyChanged?.Invoke(this, args); - } -} - - }, - { - FileName: TestClass.ReactiveProperties.g.cs, - Source: -// -#nullable enable - -using System.ComponentModel; -using System.Runtime.CompilerServices; - -/// -/// A partial class implementation for TestClass. -/// -public partial class TestClass -{ - private static readonly PropertyChangedEventArgs _virtualPropChangedEventArgs = new PropertyChangedEventArgs(nameof(VirtualProp)); - private static readonly PropertyChangedEventArgs _nonVirtualPropChangedEventArgs = new PropertyChangedEventArgs(nameof(NonVirtualProp)); - - public partial string VirtualProp - { - get => field; - set - { - if (!Equals(field, value)) - { - field = value; - OnPropertyChanged(_virtualPropChangedEventArgs); - } - } - } - - public partial string NonVirtualProp - { - get => field; - set - { - if (!Equals(field, value)) - { - field = value; - OnPropertyChanged(_nonVirtualPropChangedEventArgs); - } - } - } -} - } ], Diagnostics: null diff --git a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.GenericClassWithConstraints.verified.txt b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.GenericClassWithConstraints.verified.txt index 49c648c..4ce9ee1 100644 --- a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.GenericClassWithConstraints.verified.txt +++ b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.GenericClassWithConstraints.verified.txt @@ -21,76 +21,6 @@ sealed class ReactiveAttribute : Attribute { public ReactiveAttribute() { } } - }, - { - FileName: TestClass.INPC.g.cs, - Source: -// -#nullable enable - -using System.ComponentModel; -using System.Runtime.CompilerServices; - -public partial class TestClass : INotifyPropertyChanged where T : class, new() where U : struct -{ - public event PropertyChangedEventHandler? PropertyChanged; - - protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null) - { - PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); - } - - protected virtual void OnPropertyChanged(PropertyChangedEventArgs args) - { - PropertyChanged?.Invoke(this, args); - } -} - - }, - { - FileName: TestClass.ReactiveProperties.g.cs, - Source: -// -#nullable enable - -using System.ComponentModel; -using System.Runtime.CompilerServices; - -/// -/// A partial class implementation for TestClass{T, U}. -/// -public partial class TestClass where T : class, new() where U : struct -{ - private static readonly PropertyChangedEventArgs _referenceChangedEventArgs = new PropertyChangedEventArgs(nameof(Reference)); - private static readonly PropertyChangedEventArgs _valueChangedEventArgs = new PropertyChangedEventArgs(nameof(Value)); - - public partial T Reference - { - get => field; - set - { - if (!Equals(field, value)) - { - field = value; - OnPropertyChanged(_referenceChangedEventArgs); - } - } - } - - public partial U Value - { - get => field; - set - { - if (!Equals(field, value)) - { - field = value; - OnPropertyChanged(_valueChangedEventArgs); - } - } - } -} - } ], Diagnostics: null diff --git a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.GenericPropertyImplementation.verified.txt b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.GenericPropertyImplementation.verified.txt index 17f2882..4ce9ee1 100644 --- a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.GenericPropertyImplementation.verified.txt +++ b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.GenericPropertyImplementation.verified.txt @@ -1,58 +1,5 @@ { Sources: [ - { - FileName: GenericViewModel.INPC.g.cs, - Source: -// -#nullable enable - -using System.ComponentModel; -using System.Runtime.CompilerServices; - -internal partial class GenericViewModel : INotifyPropertyChanged -{ - public event PropertyChangedEventHandler? PropertyChanged; - - protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null) - { - PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); - } - - protected virtual void OnPropertyChanged(PropertyChangedEventArgs args) - { - PropertyChanged?.Invoke(this, args); - } -} - - }, - { - FileName: GenericViewModel.ReactiveProperties.g.cs, - Source: -// -#nullable enable - -using System.ComponentModel; -using System.Runtime.CompilerServices; - -internal partial class GenericViewModel -{ - private static readonly PropertyChangedEventArgs _valueChangedEventArgs = new PropertyChangedEventArgs(nameof(Value)); - - public partial T Value - { - get => field; - set - { - if (!Equals(field, value)) - { - field = value; - OnPropertyChanged(_valueChangedEventArgs); - } - } - } -} - - }, { FileName: IgnoreReactiveAttribute.g.cs, Source: diff --git a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.GenericPropertyWithConstraints.verified.txt b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.GenericPropertyWithConstraints.verified.txt index a6c9901..4ce9ee1 100644 --- a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.GenericPropertyWithConstraints.verified.txt +++ b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.GenericPropertyWithConstraints.verified.txt @@ -1,58 +1,5 @@ { Sources: [ - { - FileName: GenericViewModel.INPC.g.cs, - Source: -// -#nullable enable - -using System.ComponentModel; -using System.Runtime.CompilerServices; - -internal partial class GenericViewModel : INotifyPropertyChanged where T : class, new() -{ - public event PropertyChangedEventHandler? PropertyChanged; - - protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null) - { - PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); - } - - protected virtual void OnPropertyChanged(PropertyChangedEventArgs args) - { - PropertyChanged?.Invoke(this, args); - } -} - - }, - { - FileName: GenericViewModel.ReactiveProperties.g.cs, - Source: -// -#nullable enable - -using System.ComponentModel; -using System.Runtime.CompilerServices; - -internal partial class GenericViewModel where T : class, new() -{ - private static readonly PropertyChangedEventArgs _valueChangedEventArgs = new PropertyChangedEventArgs(nameof(Value)); - - public partial T Value - { - get => field; - set - { - if (!Equals(field, value)) - { - field = value; - OnPropertyChanged(_valueChangedEventArgs); - } - } - } -} - - }, { FileName: IgnoreReactiveAttribute.g.cs, Source: diff --git a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.GenericPropertyWithCustomAccessibility.verified.txt b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.GenericPropertyWithCustomAccessibility.verified.txt index bd9c1a4..4ce9ee1 100644 --- a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.GenericPropertyWithCustomAccessibility.verified.txt +++ b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.GenericPropertyWithCustomAccessibility.verified.txt @@ -1,72 +1,5 @@ { Sources: [ - { - FileName: GenericViewModel.INPC.g.cs, - Source: -// -#nullable enable - -using System.ComponentModel; -using System.Runtime.CompilerServices; - -internal partial class GenericViewModel : INotifyPropertyChanged -{ - public event PropertyChangedEventHandler? PropertyChanged; - - protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null) - { - PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); - } - - protected virtual void OnPropertyChanged(PropertyChangedEventArgs args) - { - PropertyChanged?.Invoke(this, args); - } -} - - }, - { - FileName: GenericViewModel.ReactiveProperties.g.cs, - Source: -// -#nullable enable - -using System.ComponentModel; -using System.Runtime.CompilerServices; - -internal partial class GenericViewModel -{ - private static readonly PropertyChangedEventArgs _valueChangedEventArgs = new PropertyChangedEventArgs(nameof(Value)); - private static readonly PropertyChangedEventArgs _protectedValueChangedEventArgs = new PropertyChangedEventArgs(nameof(ProtectedValue)); - - public partial T Value - { - get => field; - private set - { - if (!Equals(field, value)) - { - field = value; - OnPropertyChanged(_valueChangedEventArgs); - } - } - } - - protected partial T ProtectedValue - { - get => field; - set - { - if (!Equals(field, value)) - { - field = value; - OnPropertyChanged(_protectedValueChangedEventArgs); - } - } - } -} - - }, { FileName: IgnoreReactiveAttribute.g.cs, Source: diff --git a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.GenericPropertyWithInitSetter.verified.txt b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.GenericPropertyWithInitSetter.verified.txt index 08088b6..4ce9ee1 100644 --- a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.GenericPropertyWithInitSetter.verified.txt +++ b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.GenericPropertyWithInitSetter.verified.txt @@ -1,72 +1,5 @@ { Sources: [ - { - FileName: GenericViewModel.INPC.g.cs, - Source: -// -#nullable enable - -using System.ComponentModel; -using System.Runtime.CompilerServices; - -internal partial class GenericViewModel : INotifyPropertyChanged -{ - public event PropertyChangedEventHandler? PropertyChanged; - - protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null) - { - PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); - } - - protected virtual void OnPropertyChanged(PropertyChangedEventArgs args) - { - PropertyChanged?.Invoke(this, args); - } -} - - }, - { - FileName: GenericViewModel.ReactiveProperties.g.cs, - Source: -// -#nullable enable - -using System.ComponentModel; -using System.Runtime.CompilerServices; - -internal partial class GenericViewModel -{ - private static readonly PropertyChangedEventArgs _initValueChangedEventArgs = new PropertyChangedEventArgs(nameof(InitValue)); - private static readonly PropertyChangedEventArgs _regularValueChangedEventArgs = new PropertyChangedEventArgs(nameof(RegularValue)); - - public partial T InitValue - { - get => field; - set - { - if (!Equals(field, value)) - { - field = value; - OnPropertyChanged(_initValueChangedEventArgs); - } - } - } - - public partial T RegularValue - { - get => field; - set - { - if (!Equals(field, value)) - { - field = value; - OnPropertyChanged(_regularValueChangedEventArgs); - } - } - } -} - - }, { FileName: IgnoreReactiveAttribute.g.cs, Source: diff --git a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.GenericPropertyWithMultipleTypeParameters.verified.txt b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.GenericPropertyWithMultipleTypeParameters.verified.txt index 32eb68d..4ce9ee1 100644 --- a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.GenericPropertyWithMultipleTypeParameters.verified.txt +++ b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.GenericPropertyWithMultipleTypeParameters.verified.txt @@ -1,72 +1,5 @@ { Sources: [ - { - FileName: GenericViewModel.INPC.g.cs, - Source: -// -#nullable enable - -using System.ComponentModel; -using System.Runtime.CompilerServices; - -internal partial class GenericViewModel : INotifyPropertyChanged where T : class where U : struct -{ - public event PropertyChangedEventHandler? PropertyChanged; - - protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null) - { - PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); - } - - protected virtual void OnPropertyChanged(PropertyChangedEventArgs args) - { - PropertyChanged?.Invoke(this, args); - } -} - - }, - { - FileName: GenericViewModel.ReactiveProperties.g.cs, - Source: -// -#nullable enable - -using System.ComponentModel; -using System.Runtime.CompilerServices; - -internal partial class GenericViewModel where T : class where U : struct -{ - private static readonly PropertyChangedEventArgs _refValueChangedEventArgs = new PropertyChangedEventArgs(nameof(RefValue)); - private static readonly PropertyChangedEventArgs _valueTypeChangedEventArgs = new PropertyChangedEventArgs(nameof(ValueType)); - - public partial T? RefValue - { - get => field; - set - { - if (!Equals(field, value)) - { - field = value; - OnPropertyChanged(_refValueChangedEventArgs); - } - } - } - - public partial U ValueType - { - get => field; - set - { - if (!Equals(field, value)) - { - field = value; - OnPropertyChanged(_valueTypeChangedEventArgs); - } - } - } -} - - }, { FileName: IgnoreReactiveAttribute.g.cs, Source: diff --git a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.GenericPropertyWithNestedTypes.verified.txt b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.GenericPropertyWithNestedTypes.verified.txt index b86d047..4ce9ee1 100644 --- a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.GenericPropertyWithNestedTypes.verified.txt +++ b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.GenericPropertyWithNestedTypes.verified.txt @@ -1,72 +1,5 @@ { Sources: [ - { - FileName: GenericViewModel.INPC.g.cs, - Source: -// -#nullable enable - -using System.ComponentModel; -using System.Runtime.CompilerServices; - -internal partial class GenericViewModel : INotifyPropertyChanged -{ - public event PropertyChangedEventHandler? PropertyChanged; - - protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null) - { - PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); - } - - protected virtual void OnPropertyChanged(PropertyChangedEventArgs args) - { - PropertyChanged?.Invoke(this, args); - } -} - - }, - { - FileName: GenericViewModel.ReactiveProperties.g.cs, - Source: -// -#nullable enable - -using System.ComponentModel; -using System.Runtime.CompilerServices; - -internal partial class GenericViewModel -{ - private static readonly PropertyChangedEventArgs _listValueChangedEventArgs = new PropertyChangedEventArgs(nameof(ListValue)); - private static readonly PropertyChangedEventArgs _dictValueChangedEventArgs = new PropertyChangedEventArgs(nameof(DictValue)); - - public partial List ListValue - { - get => field; - set - { - if (!Equals(field, value)) - { - field = value; - OnPropertyChanged(_listValueChangedEventArgs); - } - } - } - - public partial Dictionary DictValue - { - get => field; - set - { - if (!Equals(field, value)) - { - field = value; - OnPropertyChanged(_dictValueChangedEventArgs); - } - } - } -} - - }, { FileName: IgnoreReactiveAttribute.g.cs, Source: diff --git a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.GenericPropertyWithNullableType.verified.txt b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.GenericPropertyWithNullableType.verified.txt index 05ec69a..4ce9ee1 100644 --- a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.GenericPropertyWithNullableType.verified.txt +++ b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.GenericPropertyWithNullableType.verified.txt @@ -1,58 +1,5 @@ { Sources: [ - { - FileName: GenericViewModel.INPC.g.cs, - Source: -// -#nullable enable - -using System.ComponentModel; -using System.Runtime.CompilerServices; - -internal partial class GenericViewModel : INotifyPropertyChanged where T : class -{ - public event PropertyChangedEventHandler? PropertyChanged; - - protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null) - { - PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); - } - - protected virtual void OnPropertyChanged(PropertyChangedEventArgs args) - { - PropertyChanged?.Invoke(this, args); - } -} - - }, - { - FileName: GenericViewModel.ReactiveProperties.g.cs, - Source: -// -#nullable enable - -using System.ComponentModel; -using System.Runtime.CompilerServices; - -internal partial class GenericViewModel where T : class -{ - private static readonly PropertyChangedEventArgs _valueChangedEventArgs = new PropertyChangedEventArgs(nameof(Value)); - - public partial T? Value - { - get => field; - set - { - if (!Equals(field, value)) - { - field = value; - OnPropertyChanged(_valueChangedEventArgs); - } - } - } -} - - }, { FileName: IgnoreReactiveAttribute.g.cs, Source: diff --git a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.GenericPropertyWithReadOnlyAccess.verified.txt b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.GenericPropertyWithReadOnlyAccess.verified.txt index f9f7813..4ce9ee1 100644 --- a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.GenericPropertyWithReadOnlyAccess.verified.txt +++ b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.GenericPropertyWithReadOnlyAccess.verified.txt @@ -1,64 +1,5 @@ { Sources: [ - { - FileName: GenericViewModel.INPC.g.cs, - Source: -// -#nullable enable - -using System.ComponentModel; -using System.Runtime.CompilerServices; - -internal partial class GenericViewModel : INotifyPropertyChanged -{ - public event PropertyChangedEventHandler? PropertyChanged; - - protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null) - { - PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); - } - - protected virtual void OnPropertyChanged(PropertyChangedEventArgs args) - { - PropertyChanged?.Invoke(this, args); - } -} - - }, - { - FileName: GenericViewModel.ReactiveProperties.g.cs, - Source: -// -#nullable enable - -using System.ComponentModel; -using System.Runtime.CompilerServices; - -internal partial class GenericViewModel -{ - private static readonly PropertyChangedEventArgs _valueChangedEventArgs = new PropertyChangedEventArgs(nameof(Value)); - private static readonly PropertyChangedEventArgs _readWriteValueChangedEventArgs = new PropertyChangedEventArgs(nameof(ReadWriteValue)); - - public partial T Value - { - get => field; - } - - public partial T ReadWriteValue - { - get => field; - set - { - if (!Equals(field, value)) - { - field = value; - OnPropertyChanged(_readWriteValueChangedEventArgs); - } - } - } -} - - }, { FileName: IgnoreReactiveAttribute.g.cs, Source: diff --git a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.InheritedReactiveAttribute.verified.txt b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.InheritedReactiveAttribute.verified.txt index 439e94b..04688ee 100644 --- a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.InheritedReactiveAttribute.verified.txt +++ b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.InheritedReactiveAttribute.verified.txt @@ -26,7 +26,7 @@ public partial class BaseViewModel : INotifyPropertyChanged }, { - FileName: BaseViewModel.ReactiveProperties.g.cs, + FileName: DerivedViewModel.ReactiveProperties.g.cs, Source: // #nullable enable @@ -35,13 +35,13 @@ using System.ComponentModel; using System.Runtime.CompilerServices; /// -/// A partial class implementation for BaseViewModel. +/// A partial class implementation for DerivedViewModel. /// -public partial class BaseViewModel +public partial class DerivedViewModel { - private static readonly PropertyChangedEventArgs _basePropChangedEventArgs = new PropertyChangedEventArgs(nameof(BaseProp)); + private static readonly PropertyChangedEventArgs _derivedPropChangedEventArgs = new PropertyChangedEventArgs(nameof(DerivedProp)); - public partial string BaseProp + public partial string DerivedProp { get => field; set @@ -49,7 +49,7 @@ public partial class BaseViewModel if (!Equals(field, value)) { field = value; - OnPropertyChanged(_basePropChangedEventArgs); + OnPropertyChanged(_derivedPropChangedEventArgs); } } } @@ -57,7 +57,18 @@ public partial class BaseViewModel }, { - FileName: DerivedViewModel.ReactiveProperties.g.cs, + FileName: IgnoreReactiveAttribute.g.cs, + Source: +using System; + +[AttributeUsage(AttributeTargets.Property, Inherited = false, AllowMultiple = false)] +sealed class IgnoreReactiveAttribute : Attribute +{ + public IgnoreReactiveAttribute() { } +} + }, + { + FileName: NonReactiveViewModel.ReactiveProperties.g.cs, Source: // #nullable enable @@ -66,13 +77,13 @@ using System.ComponentModel; using System.Runtime.CompilerServices; /// -/// A partial class implementation for DerivedViewModel. +/// A partial class implementation for NonReactiveViewModel. /// -public partial class DerivedViewModel +public partial class NonReactiveViewModel { - private static readonly PropertyChangedEventArgs _derivedPropChangedEventArgs = new PropertyChangedEventArgs(nameof(DerivedProp)); + private static readonly PropertyChangedEventArgs _ignoredPropChangedEventArgs = new PropertyChangedEventArgs(nameof(IgnoredProp)); - public partial string DerivedProp + public partial string IgnoredProp { get => field; set @@ -80,23 +91,12 @@ public partial class DerivedViewModel if (!Equals(field, value)) { field = value; - OnPropertyChanged(_derivedPropChangedEventArgs); + OnPropertyChanged(_ignoredPropChangedEventArgs); } } } } - }, - { - FileName: IgnoreReactiveAttribute.g.cs, - Source: -using System; - -[AttributeUsage(AttributeTargets.Property, Inherited = false, AllowMultiple = false)] -sealed class IgnoreReactiveAttribute : Attribute -{ - public IgnoreReactiveAttribute() { } -} }, { FileName: ReactiveAttribute.g.cs, diff --git a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.MultiLevelInheritanceWithMixedReactiveAttributes.verified.txt b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.MultiLevelInheritanceWithMixedReactiveAttributes.verified.txt index ddabbbd..82ff38f 100644 --- a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.MultiLevelInheritanceWithMixedReactiveAttributes.verified.txt +++ b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.MultiLevelInheritanceWithMixedReactiveAttributes.verified.txt @@ -26,7 +26,18 @@ public partial class BaseViewModel : INotifyPropertyChanged }, { - FileName: BaseViewModel.ReactiveProperties.g.cs, + FileName: IgnoreReactiveAttribute.g.cs, + Source: +using System; + +[AttributeUsage(AttributeTargets.Property, Inherited = false, AllowMultiple = false)] +sealed class IgnoreReactiveAttribute : Attribute +{ + public IgnoreReactiveAttribute() { } +} + }, + { + FileName: MiddleViewModel.ReactiveProperties.g.cs, Source: // #nullable enable @@ -35,13 +46,13 @@ using System.ComponentModel; using System.Runtime.CompilerServices; /// -/// A partial class implementation for BaseViewModel. +/// A partial class implementation for MiddleViewModel. /// -public partial class BaseViewModel +public partial class MiddleViewModel { - private static readonly PropertyChangedEventArgs _basePropChangedEventArgs = new PropertyChangedEventArgs(nameof(BaseProp)); + private static readonly PropertyChangedEventArgs _middlePropChangedEventArgs = new PropertyChangedEventArgs(nameof(MiddleProp)); - public partial string BaseProp + public partial string MiddleProp { get => field; set @@ -49,7 +60,7 @@ public partial class BaseViewModel if (!Equals(field, value)) { field = value; - OnPropertyChanged(_basePropChangedEventArgs); + OnPropertyChanged(_middlePropChangedEventArgs); } } } @@ -57,18 +68,7 @@ public partial class BaseViewModel }, { - FileName: IgnoreReactiveAttribute.g.cs, - Source: -using System; - -[AttributeUsage(AttributeTargets.Property, Inherited = false, AllowMultiple = false)] -sealed class IgnoreReactiveAttribute : Attribute -{ - public IgnoreReactiveAttribute() { } -} - }, - { - FileName: MiddleViewModel.ReactiveProperties.g.cs, + FileName: NonReactiveViewModel.ReactiveProperties.g.cs, Source: // #nullable enable @@ -77,13 +77,13 @@ using System.ComponentModel; using System.Runtime.CompilerServices; /// -/// A partial class implementation for MiddleViewModel. +/// A partial class implementation for NonReactiveViewModel. /// -public partial class MiddleViewModel +public partial class NonReactiveViewModel { - private static readonly PropertyChangedEventArgs _middlePropChangedEventArgs = new PropertyChangedEventArgs(nameof(MiddleProp)); + private static readonly PropertyChangedEventArgs _nonReactivePropChangedEventArgs = new PropertyChangedEventArgs(nameof(NonReactiveProp)); - public partial string MiddleProp + public partial string NonReactiveProp { get => field; set @@ -91,7 +91,7 @@ public partial class MiddleViewModel if (!Equals(field, value)) { field = value; - OnPropertyChanged(_middlePropChangedEventArgs); + OnPropertyChanged(_nonReactivePropChangedEventArgs); } } } diff --git a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.MultiLevelNestedClassesWithReactiveProperties.verified.txt b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.MultiLevelNestedClassesWithReactiveProperties.verified.txt index 4566fcf..4ce9ee1 100644 --- a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.MultiLevelNestedClassesWithReactiveProperties.verified.txt +++ b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.MultiLevelNestedClassesWithReactiveProperties.verified.txt @@ -10,68 +10,6 @@ sealed class IgnoreReactiveAttribute : Attribute { public IgnoreReactiveAttribute() { } } - }, - { - FileName: Level1.Level2.INPC.g.cs, - Source: -// -#nullable enable - -using System.ComponentModel; -using System.Runtime.CompilerServices; - -public partial class Level1 -{ - public partial class Level2 : INotifyPropertyChanged - { - public event PropertyChangedEventHandler? PropertyChanged; - - protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null) - { - PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); - } - - protected virtual void OnPropertyChanged(PropertyChangedEventArgs args) - { - PropertyChanged?.Invoke(this, args); - } - } -} - - }, - { - FileName: Level1.Level2.ReactiveProperties.g.cs, - Source: -// -#nullable enable - -using System.ComponentModel; -using System.Runtime.CompilerServices; - -public partial class Level1 -{ - /// - /// A partial class implementation for Level1.Level2. - /// - public partial class Level2 - { - private static readonly PropertyChangedEventArgs _level2PropChangedEventArgs = new PropertyChangedEventArgs(nameof(Level2Prop)); - - public partial string Level2Prop - { - get => field; - set - { - if (!Equals(field, value)) - { - field = value; - OnPropertyChanged(_level2PropChangedEventArgs); - } - } - } - } -} - }, { FileName: ReactiveAttribute.g.cs, diff --git a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.MultipleClassesWithInheritance.verified.txt b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.MultipleClassesWithInheritance.verified.txt index e13b5e2..0661312 100644 --- a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.MultipleClassesWithInheritance.verified.txt +++ b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.MultipleClassesWithInheritance.verified.txt @@ -24,37 +24,6 @@ public partial class BaseClass : INotifyPropertyChanged } } - }, - { - FileName: BaseClass.ReactiveProperties.g.cs, - Source: -// -#nullable enable - -using System.ComponentModel; -using System.Runtime.CompilerServices; - -/// -/// A partial class implementation for BaseClass. -/// -public partial class BaseClass -{ - private static readonly PropertyChangedEventArgs _basePropChangedEventArgs = new PropertyChangedEventArgs(nameof(BaseProp)); - - public partial string BaseProp - { - get => field; - set - { - if (!Equals(field, value)) - { - field = value; - OnPropertyChanged(_basePropChangedEventArgs); - } - } - } -} - }, { FileName: DerivedClass.ReactiveProperties.g.cs, diff --git a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.NestedClassWithInheritance.verified.txt b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.NestedClassWithInheritance.verified.txt index 9c557f5..fac403e 100644 --- a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.NestedClassWithInheritance.verified.txt +++ b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.NestedClassWithInheritance.verified.txt @@ -38,40 +38,6 @@ public partial class OuterClass } } - }, - { - FileName: OuterClass.InnerBase.ReactiveProperties.g.cs, - Source: -// -#nullable enable - -using System.ComponentModel; -using System.Runtime.CompilerServices; - -public partial class OuterClass -{ - /// - /// A partial class implementation for OuterClass.InnerBase. - /// - public partial class InnerBase - { - private static readonly PropertyChangedEventArgs _basePropChangedEventArgs = new PropertyChangedEventArgs(nameof(BaseProp)); - - public partial string BaseProp - { - get => field; - set - { - if (!Equals(field, value)) - { - field = value; - OnPropertyChanged(_basePropChangedEventArgs); - } - } - } - } -} - }, { FileName: OuterClass.InnerDerived.ReactiveProperties.g.cs, diff --git a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.NestedClassesWithCustomPropertyImplementation.verified.txt b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.NestedClassesWithCustomPropertyImplementation.verified.txt index ead97db..4ce9ee1 100644 --- a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.NestedClassesWithCustomPropertyImplementation.verified.txt +++ b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.NestedClassesWithCustomPropertyImplementation.verified.txt @@ -1,67 +1,5 @@ { Sources: [ - { - FileName: Container.Nested.INPC.g.cs, - Source: -// -#nullable enable - -using System.ComponentModel; -using System.Runtime.CompilerServices; - -public partial class Container -{ - public partial class Nested : INotifyPropertyChanged - { - public event PropertyChangedEventHandler? PropertyChanged; - - protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null) - { - PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); - } - - protected virtual void OnPropertyChanged(PropertyChangedEventArgs args) - { - PropertyChanged?.Invoke(this, args); - } - } -} - - }, - { - FileName: Container.Nested.ReactiveProperties.g.cs, - Source: -// -#nullable enable - -using System.ComponentModel; -using System.Runtime.CompilerServices; - -public partial class Container -{ - /// - /// A partial class implementation for Container.Nested. - /// - public partial class Nested - { - private static readonly PropertyChangedEventArgs _regularPropChangedEventArgs = new PropertyChangedEventArgs(nameof(RegularProp)); - - public partial string RegularProp - { - get => field; - set - { - if (!Equals(field, value)) - { - field = value; - OnPropertyChanged(_regularPropChangedEventArgs); - } - } - } - } -} - - }, { FileName: IgnoreReactiveAttribute.g.cs, Source: diff --git a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.NestedClassesWithDifferentAccessModifiers.verified.txt b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.NestedClassesWithDifferentAccessModifiers.verified.txt index 9f7ed54..4ce9ee1 100644 --- a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.NestedClassesWithDifferentAccessModifiers.verified.txt +++ b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.NestedClassesWithDifferentAccessModifiers.verified.txt @@ -1,300 +1,5 @@ { Sources: [ - { - FileName: Container.INPC.g.cs, - Source: -// -#nullable enable - -using System.ComponentModel; -using System.Runtime.CompilerServices; - -public partial class Container : INotifyPropertyChanged -{ - public event PropertyChangedEventHandler? PropertyChanged; - - protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null) - { - PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); - } - - protected virtual void OnPropertyChanged(PropertyChangedEventArgs args) - { - PropertyChanged?.Invoke(this, args); - } -} - - }, - { - FileName: Container.Internal.INPC.g.cs, - Source: -// -#nullable enable - -using System.ComponentModel; -using System.Runtime.CompilerServices; - -public partial class Container -{ - internal partial class Internal : INotifyPropertyChanged - { - public event PropertyChangedEventHandler? PropertyChanged; - - protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null) - { - PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); - } - - protected virtual void OnPropertyChanged(PropertyChangedEventArgs args) - { - PropertyChanged?.Invoke(this, args); - } - } -} - - }, - { - FileName: Container.Internal.ReactiveProperties.g.cs, - Source: -// -#nullable enable - -using System.ComponentModel; -using System.Runtime.CompilerServices; - -public partial class Container -{ - internal partial class Internal - { - private static readonly PropertyChangedEventArgs _internalPropChangedEventArgs = new PropertyChangedEventArgs(nameof(InternalProp)); - - public partial string InternalProp - { - get => field; - set - { - if (!Equals(field, value)) - { - field = value; - OnPropertyChanged(_internalPropChangedEventArgs); - } - } - } - } -} - - }, - { - FileName: Container.Private.INPC.g.cs, - Source: -// -#nullable enable - -using System.ComponentModel; -using System.Runtime.CompilerServices; - -public partial class Container -{ - private partial class Private : INotifyPropertyChanged - { - public event PropertyChangedEventHandler? PropertyChanged; - - protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null) - { - PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); - } - - protected virtual void OnPropertyChanged(PropertyChangedEventArgs args) - { - PropertyChanged?.Invoke(this, args); - } - } -} - - }, - { - FileName: Container.Private.ReactiveProperties.g.cs, - Source: -// -#nullable enable - -using System.ComponentModel; -using System.Runtime.CompilerServices; - -public partial class Container -{ - private partial class Private - { - private static readonly PropertyChangedEventArgs _privatePropChangedEventArgs = new PropertyChangedEventArgs(nameof(PrivateProp)); - - public partial string PrivateProp - { - get => field; - set - { - if (!Equals(field, value)) - { - field = value; - OnPropertyChanged(_privatePropChangedEventArgs); - } - } - } - } -} - - }, - { - FileName: Container.Protected.INPC.g.cs, - Source: -// -#nullable enable - -using System.ComponentModel; -using System.Runtime.CompilerServices; - -public partial class Container -{ - protected partial class Protected : INotifyPropertyChanged - { - public event PropertyChangedEventHandler? PropertyChanged; - - protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null) - { - PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); - } - - protected virtual void OnPropertyChanged(PropertyChangedEventArgs args) - { - PropertyChanged?.Invoke(this, args); - } - } -} - - }, - { - FileName: Container.Protected.ReactiveProperties.g.cs, - Source: -// -#nullable enable - -using System.ComponentModel; -using System.Runtime.CompilerServices; - -public partial class Container -{ - protected partial class Protected - { - private static readonly PropertyChangedEventArgs _protectedPropChangedEventArgs = new PropertyChangedEventArgs(nameof(ProtectedProp)); - - public partial string ProtectedProp - { - get => field; - set - { - if (!Equals(field, value)) - { - field = value; - OnPropertyChanged(_protectedPropChangedEventArgs); - } - } - } - } -} - - }, - { - FileName: Container.Public.INPC.g.cs, - Source: -// -#nullable enable - -using System.ComponentModel; -using System.Runtime.CompilerServices; - -public partial class Container -{ - public partial class Public : INotifyPropertyChanged - { - public event PropertyChangedEventHandler? PropertyChanged; - - protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null) - { - PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); - } - - protected virtual void OnPropertyChanged(PropertyChangedEventArgs args) - { - PropertyChanged?.Invoke(this, args); - } - } -} - - }, - { - FileName: Container.Public.ReactiveProperties.g.cs, - Source: -// -#nullable enable - -using System.ComponentModel; -using System.Runtime.CompilerServices; - -public partial class Container -{ - /// - /// A partial class implementation for Container.Public. - /// - public partial class Public - { - private static readonly PropertyChangedEventArgs _publicPropChangedEventArgs = new PropertyChangedEventArgs(nameof(PublicProp)); - - public partial string PublicProp - { - get => field; - set - { - if (!Equals(field, value)) - { - field = value; - OnPropertyChanged(_publicPropChangedEventArgs); - } - } - } - } -} - - }, - { - FileName: Container.ReactiveProperties.g.cs, - Source: -// -#nullable enable - -using System.ComponentModel; -using System.Runtime.CompilerServices; - -/// -/// A partial class implementation for Container. -/// -public partial class Container -{ - private static readonly PropertyChangedEventArgs _containerPropChangedEventArgs = new PropertyChangedEventArgs(nameof(ContainerProp)); - - public partial string ContainerProp - { - get => field; - set - { - if (!Equals(field, value)) - { - field = value; - OnPropertyChanged(_containerPropChangedEventArgs); - } - } - } -} - - }, { FileName: IgnoreReactiveAttribute.g.cs, Source: diff --git a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.NestedClassesWithGenericConstraints.verified.txt b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.NestedClassesWithGenericConstraints.verified.txt index 01a29e6..4ce9ee1 100644 --- a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.NestedClassesWithGenericConstraints.verified.txt +++ b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.NestedClassesWithGenericConstraints.verified.txt @@ -1,95 +1,5 @@ { Sources: [ - { - FileName: Container.Nested.INPC.g.cs, - Source: -// -#nullable enable - -using System.ComponentModel; -using System.Runtime.CompilerServices; - -public partial class Container -{ - public partial class Nested : INotifyPropertyChanged where U : struct - { - public event PropertyChangedEventHandler? PropertyChanged; - - protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null) - { - PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); - } - - protected virtual void OnPropertyChanged(PropertyChangedEventArgs args) - { - PropertyChanged?.Invoke(this, args); - } - } -} - - }, - { - FileName: Container.Nested.ReactiveProperties.g.cs, - Source: -// -#nullable enable - -using System.ComponentModel; -using System.Runtime.CompilerServices; - -public partial class Container -{ - /// - /// A partial class implementation for Container{T}.Nested{U}. - /// - public partial class Nested where U : struct - { - private static readonly PropertyChangedEventArgs _refPropChangedEventArgs = new PropertyChangedEventArgs(nameof(RefProp)); - private static readonly PropertyChangedEventArgs _valuePropChangedEventArgs = new PropertyChangedEventArgs(nameof(ValueProp)); - private static readonly PropertyChangedEventArgs _complexPropChangedEventArgs = new PropertyChangedEventArgs(nameof(ComplexProp)); - - public partial T? RefProp - { - get => field; - set - { - if (!Equals(field, value)) - { - field = value; - OnPropertyChanged(_refPropChangedEventArgs); - } - } - } - - public partial U ValueProp - { - get => field; - set - { - if (!Equals(field, value)) - { - field = value; - OnPropertyChanged(_valuePropChangedEventArgs); - } - } - } - - public partial Dictionary> ComplexProp - { - get => field; - set - { - if (!Equals(field, value)) - { - field = value; - OnPropertyChanged(_complexPropChangedEventArgs); - } - } - } - } -} - - }, { FileName: IgnoreReactiveAttribute.g.cs, Source: diff --git a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.NestedClassesWithInheritanceAndInterfaces.verified.txt b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.NestedClassesWithInheritanceAndInterfaces.verified.txt index 4c4170a..eb919f5 100644 --- a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.NestedClassesWithInheritanceAndInterfaces.verified.txt +++ b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.NestedClassesWithInheritanceAndInterfaces.verified.txt @@ -27,40 +27,6 @@ public partial class Container } } - }, - { - FileName: Container.NestedBase.ReactiveProperties.g.cs, - Source: -// -#nullable enable - -using System.ComponentModel; -using System.Runtime.CompilerServices; - -public partial class Container -{ - /// - /// A partial class implementation for Container.NestedBase. - /// - public partial class NestedBase - { - private static readonly PropertyChangedEventArgs _virtualPropChangedEventArgs = new PropertyChangedEventArgs(nameof(VirtualProp)); - - public partial string VirtualProp - { - get => field; - set - { - if (!Equals(field, value)) - { - field = value; - OnPropertyChanged(_virtualPropChangedEventArgs); - } - } - } - } -} - }, { FileName: Container.NestedDerived.ReactiveProperties.g.cs, diff --git a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.NestedClassesWithInitOnlyProperties.verified.txt b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.NestedClassesWithInitOnlyProperties.verified.txt index 34efdd2..4ce9ee1 100644 --- a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.NestedClassesWithInitOnlyProperties.verified.txt +++ b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.NestedClassesWithInitOnlyProperties.verified.txt @@ -1,81 +1,5 @@ { Sources: [ - { - FileName: Container.Nested.INPC.g.cs, - Source: -// -#nullable enable - -using System.ComponentModel; -using System.Runtime.CompilerServices; - -public partial class Container -{ - public partial class Nested : INotifyPropertyChanged - { - public event PropertyChangedEventHandler? PropertyChanged; - - protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null) - { - PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); - } - - protected virtual void OnPropertyChanged(PropertyChangedEventArgs args) - { - PropertyChanged?.Invoke(this, args); - } - } -} - - }, - { - FileName: Container.Nested.ReactiveProperties.g.cs, - Source: -// -#nullable enable - -using System.ComponentModel; -using System.Runtime.CompilerServices; - -public partial class Container -{ - /// - /// A partial class implementation for Container.Nested. - /// - public partial class Nested - { - private static readonly PropertyChangedEventArgs _regularPropChangedEventArgs = new PropertyChangedEventArgs(nameof(RegularProp)); - private static readonly PropertyChangedEventArgs _initOnlyPropChangedEventArgs = new PropertyChangedEventArgs(nameof(InitOnlyProp)); - - public partial string RegularProp - { - get => field; - set - { - if (!Equals(field, value)) - { - field = value; - OnPropertyChanged(_regularPropChangedEventArgs); - } - } - } - - public partial string InitOnlyProp - { - get => field; - set - { - if (!Equals(field, value)) - { - field = value; - OnPropertyChanged(_initOnlyPropChangedEventArgs); - } - } - } - } -} - - }, { FileName: IgnoreReactiveAttribute.g.cs, Source: diff --git a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.NestedClassesWithMixedReactiveScopes.verified.txt b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.NestedClassesWithMixedReactiveScopes.verified.txt index 1b789de..9f37bb4 100644 --- a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.NestedClassesWithMixedReactiveScopes.verified.txt +++ b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.NestedClassesWithMixedReactiveScopes.verified.txt @@ -114,71 +114,6 @@ public partial class Container } } - }, - { - FileName: Container.ReactiveNested.ReactiveProperties.g.cs, - Source: -// -#nullable enable - -using System.ComponentModel; -using System.Runtime.CompilerServices; - -public partial class Container -{ - /// - /// A partial class implementation for Container.ReactiveNested. - /// - public partial class ReactiveNested - { - private static readonly PropertyChangedEventArgs _allPropsReactivePropChangedEventArgs = new PropertyChangedEventArgs(nameof(AllPropsReactiveProp)); - - public partial string AllPropsReactiveProp - { - get => field; - set - { - if (!Equals(field, value)) - { - field = value; - OnPropertyChanged(_allPropsReactivePropChangedEventArgs); - } - } - } - } -} - - }, - { - FileName: Container.ReactiveProperties.g.cs, - Source: -// -#nullable enable - -using System.ComponentModel; -using System.Runtime.CompilerServices; - -/// -/// A partial class implementation for Container. -/// -public partial class Container -{ - private static readonly PropertyChangedEventArgs _containerPropChangedEventArgs = new PropertyChangedEventArgs(nameof(ContainerProp)); - - public partial string ContainerProp - { - get => field; - set - { - if (!Equals(field, value)) - { - field = value; - OnPropertyChanged(_containerPropChangedEventArgs); - } - } - } -} - }, { FileName: IgnoreReactiveAttribute.g.cs, diff --git a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.NestedClassesWithStaticAndInstanceMembers.verified.txt b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.NestedClassesWithStaticAndInstanceMembers.verified.txt index 3e18b90..4ce9ee1 100644 --- a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.NestedClassesWithStaticAndInstanceMembers.verified.txt +++ b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.NestedClassesWithStaticAndInstanceMembers.verified.txt @@ -1,81 +1,5 @@ { Sources: [ - { - FileName: Container.Nested.INPC.g.cs, - Source: -// -#nullable enable - -using System.ComponentModel; -using System.Runtime.CompilerServices; - -public partial class Container -{ - public partial class Nested : INotifyPropertyChanged - { - public event PropertyChangedEventHandler? PropertyChanged; - - protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null) - { - PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); - } - - protected virtual void OnPropertyChanged(PropertyChangedEventArgs args) - { - PropertyChanged?.Invoke(this, args); - } - } -} - - }, - { - FileName: Container.Nested.ReactiveProperties.g.cs, - Source: -// -#nullable enable - -using System.ComponentModel; -using System.Runtime.CompilerServices; - -public partial class Container -{ - /// - /// A partial class implementation for Container.Nested. - /// - public partial class Nested - { - private static readonly PropertyChangedEventArgs _staticPropChangedEventArgs = new PropertyChangedEventArgs(nameof(StaticProp)); - private static readonly PropertyChangedEventArgs _instancePropChangedEventArgs = new PropertyChangedEventArgs(nameof(InstanceProp)); - - public partial string StaticProp - { - get => field; - set - { - if (!Equals(field, value)) - { - field = value; - OnPropertyChanged(_staticPropChangedEventArgs); - } - } - } - - public partial string InstanceProp - { - get => field; - set - { - if (!Equals(field, value)) - { - field = value; - OnPropertyChanged(_instancePropChangedEventArgs); - } - } - } - } -} - - }, { FileName: IgnoreReactiveAttribute.g.cs, Source: diff --git a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.NestedPrivateClassWithReactiveProperties.verified.txt b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.NestedPrivateClassWithReactiveProperties.verified.txt index 5dedddc..4ce9ee1 100644 --- a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.NestedPrivateClassWithReactiveProperties.verified.txt +++ b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.NestedPrivateClassWithReactiveProperties.verified.txt @@ -10,138 +10,6 @@ sealed class IgnoreReactiveAttribute : Attribute { public IgnoreReactiveAttribute() { } } - }, - { - FileName: OuterClass.PrivateInnerClass.INPC.g.cs, - Source: -// -#nullable enable - -using System.ComponentModel; -using System.Runtime.CompilerServices; - -public partial class OuterClass -{ - private partial class PrivateInnerClass : INotifyPropertyChanged - { - public event PropertyChangedEventHandler? PropertyChanged; - - protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null) - { - PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); - } - - protected virtual void OnPropertyChanged(PropertyChangedEventArgs args) - { - PropertyChanged?.Invoke(this, args); - } - } -} - - }, - { - FileName: OuterClass.PrivateInnerClass.ReactiveProperties.g.cs, - Source: -// -#nullable enable - -using System.ComponentModel; -using System.Runtime.CompilerServices; - -public partial class OuterClass -{ - private partial class PrivateInnerClass - { - private static readonly PropertyChangedEventArgs _innerPropChangedEventArgs = new PropertyChangedEventArgs(nameof(InnerProp)); - private static readonly PropertyChangedEventArgs _privateInnerPropChangedEventArgs = new PropertyChangedEventArgs(nameof(PrivateInnerProp)); - - public partial string InnerProp - { - get => field; - set - { - if (!Equals(field, value)) - { - field = value; - OnPropertyChanged(_innerPropChangedEventArgs); - } - } - } - - private partial int PrivateInnerProp - { - get => field; - set - { - if (!Equals(field, value)) - { - field = value; - OnPropertyChanged(_privateInnerPropChangedEventArgs); - } - } - } - } -} - - }, - { - FileName: OuterClass.ProtectedInnerClass.INPC.g.cs, - Source: -// -#nullable enable - -using System.ComponentModel; -using System.Runtime.CompilerServices; - -public partial class OuterClass -{ - protected partial class ProtectedInnerClass : INotifyPropertyChanged - { - public event PropertyChangedEventHandler? PropertyChanged; - - protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null) - { - PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); - } - - protected virtual void OnPropertyChanged(PropertyChangedEventArgs args) - { - PropertyChanged?.Invoke(this, args); - } - } -} - - }, - { - FileName: OuterClass.ProtectedInnerClass.ReactiveProperties.g.cs, - Source: -// -#nullable enable - -using System.ComponentModel; -using System.Runtime.CompilerServices; - -public partial class OuterClass -{ - protected partial class ProtectedInnerClass - { - private static readonly PropertyChangedEventArgs _protectedClassPropChangedEventArgs = new PropertyChangedEventArgs(nameof(ProtectedClassProp)); - - public partial string ProtectedClassProp - { - get => field; - set - { - if (!Equals(field, value)) - { - field = value; - OnPropertyChanged(_protectedClassPropChangedEventArgs); - } - } - } - } -} - }, { FileName: ReactiveAttribute.g.cs, diff --git a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.SimpleClassWithReactiveAttribute.verified.txt b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.SimpleClassWithReactiveAttribute.verified.txt index 3ecc45f..4ce9ee1 100644 --- a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.SimpleClassWithReactiveAttribute.verified.txt +++ b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.SimpleClassWithReactiveAttribute.verified.txt @@ -21,62 +21,6 @@ sealed class ReactiveAttribute : Attribute { public ReactiveAttribute() { } } - }, - { - FileName: TestClass.INPC.g.cs, - Source: -// -#nullable enable - -using System.ComponentModel; -using System.Runtime.CompilerServices; - -public partial class TestClass : INotifyPropertyChanged -{ - public event PropertyChangedEventHandler? PropertyChanged; - - protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null) - { - PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); - } - - protected virtual void OnPropertyChanged(PropertyChangedEventArgs args) - { - PropertyChanged?.Invoke(this, args); - } -} - - }, - { - FileName: TestClass.ReactiveProperties.g.cs, - Source: -// -#nullable enable - -using System.ComponentModel; -using System.Runtime.CompilerServices; - -/// -/// A partial class implementation for TestClass. -/// -public partial class TestClass -{ - private static readonly PropertyChangedEventArgs _nameChangedEventArgs = new PropertyChangedEventArgs(nameof(Name)); - - public partial string Name - { - get => field; - set - { - if (!Equals(field, value)) - { - field = value; - OnPropertyChanged(_nameChangedEventArgs); - } - } - } -} - } ], Diagnostics: null diff --git a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.UseLegacyModeTest.verified.txt b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.UseLegacyModeTest.verified.txt index c342953..4ce9ee1 100644 --- a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.UseLegacyModeTest.verified.txt +++ b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.UseLegacyModeTest.verified.txt @@ -21,64 +21,6 @@ sealed class ReactiveAttribute : Attribute { public ReactiveAttribute() { } } - }, - { - FileName: TestClass.INPC.g.cs, - Source: -// -#nullable enable - -using System.ComponentModel; -using System.Runtime.CompilerServices; - -public partial class TestClass : INotifyPropertyChanged -{ - public event PropertyChangedEventHandler? PropertyChanged; - - protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null) - { - PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); - } - - protected virtual void OnPropertyChanged(PropertyChangedEventArgs args) - { - PropertyChanged?.Invoke(this, args); - } -} - - }, - { - FileName: TestClass.ReactiveProperties.g.cs, - Source: -// -#nullable enable - -using System.ComponentModel; -using System.Runtime.CompilerServices; - -/// -/// A partial class implementation for TestClass. -/// -public partial class TestClass -{ - private string _name; - - private static readonly PropertyChangedEventArgs _nameChangedEventArgs = new PropertyChangedEventArgs(nameof(Name)); - - public partial string Name - { - get => _name; - set - { - if (!Equals(_name, value)) - { - _name = value; - OnPropertyChanged(_nameChangedEventArgs); - } - } - } -} - } ], Diagnostics: null From 03dc50df074c6eb28d3f860e63533c32b472a54c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wies=C5=82aw=20S=CC=8Colte=CC=81s?= Date: Wed, 25 Dec 2024 20:25:26 +0100 Subject: [PATCH 07/10] Update ReactiveGenerator.cs --- ReactiveGenerator/ReactiveGenerator.cs | 193 +++++-------------------- 1 file changed, 39 insertions(+), 154 deletions(-) diff --git a/ReactiveGenerator/ReactiveGenerator.cs b/ReactiveGenerator/ReactiveGenerator.cs index 41c6430..55d41ea 100644 --- a/ReactiveGenerator/ReactiveGenerator.cs +++ b/ReactiveGenerator/ReactiveGenerator.cs @@ -1,5 +1,4 @@ -using System; -using System.Collections.Generic; +using System.Collections.Generic; using System.Linq; using System.Text; using Microsoft.CodeAnalysis; @@ -12,10 +11,7 @@ namespace ReactiveGenerator; [Generator] public class ReactiveGenerator : IIncrementalGenerator { - private static INamedTypeSymbol? s_reactiveAttributeSymbol; - private static INamedTypeSymbol? s_ignoreReactiveAttributeSymbol; - - private record PropertyInfo( + private record PropertyInfo( IPropertySymbol Property, bool HasReactiveAttribute, bool HasIgnoreAttribute, @@ -23,25 +19,13 @@ private record PropertyInfo( public void Initialize(IncrementalGeneratorInitializationContext context) { + // Register both attributes context.RegisterPostInitializationOutput(ctx => { ctx.AddSource("ReactiveAttribute.g.cs", SourceText.From(AttributeSource, Encoding.UTF8)); ctx.AddSource("IgnoreReactiveAttribute.g.cs", SourceText.From(IgnoreAttributeSource, Encoding.UTF8)); }); - // Cache known attribute symbols - var compilationProvider = context.CompilationProvider.Select((comp, _) => - { - s_reactiveAttributeSymbol = comp.GetTypeByMetadataName("ReactiveAttribute"); - // or if your attribute is in a namespace, e.g. "MyNamespace.ReactiveAttribute", - // use that full name instead: - // s_reactiveAttributeSymbol = comp.GetTypeByMetadataName("MyNamespace.ReactiveAttribute"); - - s_ignoreReactiveAttributeSymbol = comp.GetTypeByMetadataName("IgnoreReactiveAttribute"); - // ... - return comp; - }); - // Get MSBuild property for enabling legacy mode var useLegacyMode = context.AnalyzerConfigOptionsProvider .Select((provider, _) => bool.TryParse( @@ -85,36 +69,26 @@ public void Initialize(IncrementalGeneratorInitializationContext context) private static bool IsTypeReactive(INamedTypeSymbol type) { + // If type inherits from ReactiveObject, it's already reactive if (InheritsFromReactiveObject(type)) return true; - // Check for [IgnoreReactive] + // First check if the type has [IgnoreReactive] foreach (var attribute in type.GetAttributes()) { - if (SymbolEqualityComparer.Default.Equals(attribute.AttributeClass, s_ignoreReactiveAttributeSymbol)) + if (attribute.AttributeClass?.Name is "IgnoreReactiveAttribute" or "IgnoreReactive") return false; } - // Check for [Reactive] - foreach (var attribute in type.GetAttributes()) - { - if (SymbolEqualityComparer.Default.Equals(attribute.AttributeClass, s_reactiveAttributeSymbol)) - return true; - } - - // Finally check base types (excluding ReactiveObject) - var current = type.BaseType; + // Then check if the type has [Reactive] (including base types) + var current = type; while (current != null) { - if (InheritsFromReactiveObject(current)) - return true; - foreach (var attribute in current.GetAttributes()) { if (attribute.AttributeClass?.Name is "ReactiveAttribute" or "Reactive") return true; } - current = current.BaseType; } @@ -144,14 +118,14 @@ private static (INamedTypeSymbol Type, Location Location)? GetClassInfo(Generato if (context.Node is not PropertyDeclarationSyntax propertyDeclaration) return null; - // Get the symbol for the property var symbol = context.SemanticModel.GetDeclaredSymbol(propertyDeclaration) as IPropertySymbol; - if (symbol is null) + if (symbol == null) return null; - // Check property-level attributes for [Reactive] or [IgnoreReactive] bool hasReactiveAttribute = false; bool hasIgnoreAttribute = false; + + // Check property attributes foreach (var attributeList in propertyDeclaration.AttributeLists) { foreach (var attribute in attributeList.Attributes) @@ -164,30 +138,18 @@ private static (INamedTypeSymbol Type, Location Location)? GetClassInfo(Generato } } - // Check if containing type is "reactive" - var containingType = symbol.ContainingType; - bool classHasReactiveAttribute = IsTypeReactive(containingType); + // Check if containing type should be reactive + bool classHasReactiveAttribute = IsTypeReactive(symbol.ContainingType); - // Check if user code has a non-trivial implementation - // (block body or expression body with real logic) + // Check if property has an implementation bool hasImplementation = propertyDeclaration.AccessorList?.Accessors.Any( - a => a.Body != null || a.ExpressionBody != null - ) ?? false; + a => a.Body != null || a.ExpressionBody != null) ?? false; - // If it's only "get => field" / "set => field = value" logic, treat it as no real user implementation - if (hasImplementation && IsTrivialFieldImplementation(propertyDeclaration)) - { - hasImplementation = false; - } - - // Decide if we should generate code - // We do so if: - // 1) The property or class is [Reactive], - // 2) There's no [IgnoreReactive], - // 3) The property doesn't already have a non-trivial implementation - if ((hasReactiveAttribute || (classHasReactiveAttribute && !hasIgnoreAttribute)) && - !hasIgnoreAttribute && - !hasImplementation) + // Return property info if it either: + // 1. Has [Reactive] attribute directly + // 2. Is in a class with [Reactive] attribute and doesn't have [IgnoreReactive] + // 3. Has no implementation yet + if ((hasReactiveAttribute || (classHasReactiveAttribute && !hasIgnoreAttribute)) && !hasImplementation) { return new PropertyInfo(symbol, hasReactiveAttribute, hasIgnoreAttribute, hasImplementation); } @@ -195,70 +157,6 @@ private static (INamedTypeSymbol Type, Location Location)? GetClassInfo(Generato return null; } - private static bool IsTrivialFieldImplementation(PropertyDeclarationSyntax propertyDeclaration) - { - if (propertyDeclaration.AccessorList is null) - return false; - - foreach (var accessor in propertyDeclaration.AccessorList.Accessors) - { - // If there's a block body { ... }, it's definitely not trivial - if (accessor.Body != null) - return false; - - // Check if it's an expression-bodied accessor - // like `get => field;`, `set => field = value;` - if (accessor.ExpressionBody != null) - { - var exprText = accessor.ExpressionBody.Expression.ToString().Trim(); - - if (accessor.Keyword.IsKind(SyntaxKind.GetKeyword)) - { - // Allowed minimal forms: - // - "field" - // - "field ?? something" - // You can expand as you like (e.g. "field ?? string.Empty") - if (!IsAllowedGetExpression(exprText)) - return false; - } - else if (accessor.Keyword.IsKind(SyntaxKind.SetKeyword)) - { - // Allowed minimal form: - // - "field = value" - // Possibly "field = value ?? something" if you wanted to allow that - if (!IsAllowedSetExpression(exprText)) - return false; - } - } - } - - // If we never returned false, it means all accessors are trivial "field" usage - return true; - } - - private static bool IsAllowedGetExpression(string expr) - { - // For example: - // "field" - // "field ?? string.Empty" - // "field ?? \"\"" - // or anything else you want to treat as "trivial" - if (expr == "field") - return true; - - if (expr.StartsWith("field ??", StringComparison.Ordinal)) - return true; - - return false; - } - - private static bool IsAllowedSetExpression(string expr) - { - // For instance, "field = value" - // If you want to allow "field = value ?? something", add logic - return expr == "field = value"; - } - private static bool InheritsFromReactiveObject(INamedTypeSymbol typeSymbol) { var current = typeSymbol; @@ -369,12 +267,12 @@ private static void Execute( var processedTypes = new HashSet(SymbolEqualityComparer.Default); var allTypes = new HashSet(SymbolEqualityComparer.Default); - // Group partial properties by containing type + // Group properties by containing type var propertyGroups = properties .GroupBy(p => p.Property.ContainingType, SymbolEqualityComparer.Default) .ToDictionary(g => g.Key, g => g.ToList(), SymbolEqualityComparer.Default); - // Gather all candidate types from the compilation + // Add types that need processing foreach (var type in GetAllTypesInCompilation(compilation)) { if (IsTypeMarkedReactive(type) || HasAnyReactiveProperties(type, propertyGroups)) @@ -383,30 +281,22 @@ private static void Execute( } } - // Sort types so base classes come before derived + // Process types in correct order foreach (var type in allTypes.OrderBy(t => GetTypeHierarchyDepth(t))) { if (processedTypes.Contains(type)) continue; - // If the class or any of its base types physically inherits from ReactiveObject, - // we won't generate an INotifyPropertyChanged partial - bool isReactiveObjectDerived = InheritsFromReactiveObject(type); - - // Check if the type or base types physically implement INotifyPropertyChanged, - // or if we've already processed them in this compilation - bool alreadyHasInpc = isReactiveObjectDerived || - HasINPCImplementation(compilation, type, processedTypes); + var isReactiveObjectDerived = InheritsFromReactiveObject(type); - // If not already present, create the INPC partial - if (!alreadyHasInpc) + // Generate INPC implementation if needed + if (!isReactiveObjectDerived && !HasINPCImplementation(compilation, type, processedTypes)) { var inpcSource = GenerateINPCImplementation(type); if (!string.IsNullOrEmpty(inpcSource)) { var fullTypeName = type.ToDisplayString(new SymbolDisplayFormat( - typeQualificationStyle: SymbolDisplayTypeQualificationStyle - .NameAndContainingTypesAndNamespaces, + typeQualificationStyle: SymbolDisplayTypeQualificationStyle.NameAndContainingTypesAndNamespaces, genericsOptions: SymbolDisplayGenericsOptions.None, miscellaneousOptions: SymbolDisplayMiscellaneousOptions.None)); @@ -415,22 +305,20 @@ private static void Execute( } } - // Generate property partials for [Reactive] or class-level [Reactive] - // (skipping those with [IgnoreReactive], or that have an existing implementation) + // Generate property implementations if (propertyGroups.TryGetValue(type, out var typeProperties)) { - bool isTypeReactive = IsTypeMarkedReactive(type); - + var isTypeReactive = IsTypeMarkedReactive(type); var reactiveProperties = typeProperties .Where(p => !p.HasImplementation && !p.HasIgnoreAttribute && - (p.HasReactiveAttribute || isTypeReactive)) + (p.HasReactiveAttribute || // Include properties marked with [Reactive] + isTypeReactive)) // Include all properties if class is marked with [Reactive] .Select(p => p.Property) .ToList(); if (reactiveProperties.Any()) { - // We do *not* generate a second INPC block here, just the property expansions var source = GenerateClassSource( type, reactiveProperties, @@ -455,33 +343,30 @@ private static void Execute( } } - private static bool HasINPCImplementation( - Compilation compilation, - INamedTypeSymbol typeSymbol, + private static bool HasINPCImplementation(Compilation compilation, INamedTypeSymbol typeSymbol, HashSet processedTypes) { var inpcType = compilation.GetTypeByMetadataName("System.ComponentModel.INotifyPropertyChanged"); if (inpcType is null) return false; - // 1. If the type physically implements INPC via AllInterfaces + // First check if current type implements INPC directly if (typeSymbol.AllInterfaces.Contains(inpcType, SymbolEqualityComparer.Default)) return true; - // 2. If the generator has *already* processed this type in this compilation - // (thus added a partial INPC), it effectively has INPC. + // Check if current type is in processedTypes (will have INPC implemented) if (processedTypes.Contains(typeSymbol)) return true; - // 3. Check base types recursively + // Check base types recursively var current = typeSymbol.BaseType; while (current is not null) { - // If the base physically implements INPC + // Check if base type implements INPC directly if (current.AllInterfaces.Contains(inpcType, SymbolEqualityComparer.Default)) return true; - // If the base was processed by this generator + // Check if base type is in processedTypes if (processedTypes.Contains(current)) return true; @@ -983,7 +868,7 @@ private static string GetEventArgsFieldName(string propertyName) private const string AttributeSource = @"using System; -[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = false, AllowMultiple = false)] +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = true, AllowMultiple = false)] sealed class ReactiveAttribute : Attribute { public ReactiveAttribute() { } @@ -991,7 +876,7 @@ public ReactiveAttribute() { } private const string IgnoreAttributeSource = @"using System; -[AttributeUsage(AttributeTargets.Property, Inherited = false, AllowMultiple = false)] +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = false, AllowMultiple = false)] sealed class IgnoreReactiveAttribute : Attribute { public IgnoreReactiveAttribute() { } From 1680333b6aa6caccc201c9eb6ab6e29391997292 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wies=C5=82aw=20S=CC=8Colte=CC=81s?= Date: Wed, 25 Dec 2024 20:25:31 +0100 Subject: [PATCH 08/10] Update --- ...ect_ThenNoDoubleINPCInDerived.verified.txt | 4 +-- ...ctive_ThenDerivedIgnoresItToo.verified.txt | 32 ++----------------- ...tive_ThenNoExtraINPCInDerived.verified.txt | 4 +-- ...ass_ThenNoDoubleINPCInDerived.verified.txt | 32 ++----------------- 4 files changed, 8 insertions(+), 64 deletions(-) diff --git a/ReactiveGenerator.Tests/Snapshots/CrossAssemblyTests.ExternalBaseDerivedFromReactiveObject_ThenNoDoubleINPCInDerived.verified.txt b/ReactiveGenerator.Tests/Snapshots/CrossAssemblyTests.ExternalBaseDerivedFromReactiveObject_ThenNoDoubleINPCInDerived.verified.txt index 51b7470..0bdc738 100644 --- a/ReactiveGenerator.Tests/Snapshots/CrossAssemblyTests.ExternalBaseDerivedFromReactiveObject_ThenNoDoubleINPCInDerived.verified.txt +++ b/ReactiveGenerator.Tests/Snapshots/CrossAssemblyTests.ExternalBaseDerivedFromReactiveObject_ThenNoDoubleINPCInDerived.verified.txt @@ -5,7 +5,7 @@ Source: using System; -[AttributeUsage(AttributeTargets.Property, Inherited = false, AllowMultiple = false)] +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = false, AllowMultiple = false)] sealed class IgnoreReactiveAttribute : Attribute { public IgnoreReactiveAttribute() { } @@ -40,7 +40,7 @@ namespace MainLib Source: using System; -[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = false, AllowMultiple = false)] +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = true, AllowMultiple = false)] sealed class ReactiveAttribute : Attribute { public ReactiveAttribute() { } diff --git a/ReactiveGenerator.Tests/Snapshots/CrossAssemblyTests.ExternalBaseHasIgnoreReactive_ThenDerivedIgnoresItToo.verified.txt b/ReactiveGenerator.Tests/Snapshots/CrossAssemblyTests.ExternalBaseHasIgnoreReactive_ThenDerivedIgnoresItToo.verified.txt index 4997f24..c798da6 100644 --- a/ReactiveGenerator.Tests/Snapshots/CrossAssemblyTests.ExternalBaseHasIgnoreReactive_ThenDerivedIgnoresItToo.verified.txt +++ b/ReactiveGenerator.Tests/Snapshots/CrossAssemblyTests.ExternalBaseHasIgnoreReactive_ThenDerivedIgnoresItToo.verified.txt @@ -1,39 +1,11 @@ { Sources: [ - { - FileName: ExternalLib.BaseWithIgnore.INPC.g.cs, - Source: -// -#nullable enable - -using System.ComponentModel; -using System.Runtime.CompilerServices; - -namespace ExternalLib -{ - public partial class BaseWithIgnore : INotifyPropertyChanged - { - public event PropertyChangedEventHandler? PropertyChanged; - - protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null) - { - PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); - } - - protected virtual void OnPropertyChanged(PropertyChangedEventArgs args) - { - PropertyChanged?.Invoke(this, args); - } - } -} - - }, { FileName: IgnoreReactiveAttribute.g.cs, Source: using System; -[AttributeUsage(AttributeTargets.Property, Inherited = false, AllowMultiple = false)] +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = false, AllowMultiple = false)] sealed class IgnoreReactiveAttribute : Attribute { public IgnoreReactiveAttribute() { } @@ -78,7 +50,7 @@ namespace MainLib Source: using System; -[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = false, AllowMultiple = false)] +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = true, AllowMultiple = false)] sealed class ReactiveAttribute : Attribute { public ReactiveAttribute() { } diff --git a/ReactiveGenerator.Tests/Snapshots/CrossAssemblyTests.ExternalBaseHasPropertyLevelReactive_ThenNoExtraINPCInDerived.verified.txt b/ReactiveGenerator.Tests/Snapshots/CrossAssemblyTests.ExternalBaseHasPropertyLevelReactive_ThenNoExtraINPCInDerived.verified.txt index 98e5f5a..3a30ebe 100644 --- a/ReactiveGenerator.Tests/Snapshots/CrossAssemblyTests.ExternalBaseHasPropertyLevelReactive_ThenNoExtraINPCInDerived.verified.txt +++ b/ReactiveGenerator.Tests/Snapshots/CrossAssemblyTests.ExternalBaseHasPropertyLevelReactive_ThenNoExtraINPCInDerived.verified.txt @@ -5,7 +5,7 @@ Source: using System; -[AttributeUsage(AttributeTargets.Property, Inherited = false, AllowMultiple = false)] +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = false, AllowMultiple = false)] sealed class IgnoreReactiveAttribute : Attribute { public IgnoreReactiveAttribute() { } @@ -50,7 +50,7 @@ namespace MainLib Source: using System; -[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = false, AllowMultiple = false)] +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = true, AllowMultiple = false)] sealed class ReactiveAttribute : Attribute { public ReactiveAttribute() { } diff --git a/ReactiveGenerator.Tests/Snapshots/CrossAssemblyTests.ExternalBaseHasReactiveClass_ThenNoDoubleINPCInDerived.verified.txt b/ReactiveGenerator.Tests/Snapshots/CrossAssemblyTests.ExternalBaseHasReactiveClass_ThenNoDoubleINPCInDerived.verified.txt index 83aff6d..c7718c2 100644 --- a/ReactiveGenerator.Tests/Snapshots/CrossAssemblyTests.ExternalBaseHasReactiveClass_ThenNoDoubleINPCInDerived.verified.txt +++ b/ReactiveGenerator.Tests/Snapshots/CrossAssemblyTests.ExternalBaseHasReactiveClass_ThenNoDoubleINPCInDerived.verified.txt @@ -1,39 +1,11 @@ { Sources: [ - { - FileName: ExternalLib.ExternalBase.INPC.g.cs, - Source: -// -#nullable enable - -using System.ComponentModel; -using System.Runtime.CompilerServices; - -namespace ExternalLib -{ - public partial class ExternalBase : INotifyPropertyChanged - { - public event PropertyChangedEventHandler? PropertyChanged; - - protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null) - { - PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); - } - - protected virtual void OnPropertyChanged(PropertyChangedEventArgs args) - { - PropertyChanged?.Invoke(this, args); - } - } -} - - }, { FileName: IgnoreReactiveAttribute.g.cs, Source: using System; -[AttributeUsage(AttributeTargets.Property, Inherited = false, AllowMultiple = false)] +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = false, AllowMultiple = false)] sealed class IgnoreReactiveAttribute : Attribute { public IgnoreReactiveAttribute() { } @@ -78,7 +50,7 @@ namespace MainLib Source: using System; -[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = false, AllowMultiple = false)] +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = true, AllowMultiple = false)] sealed class ReactiveAttribute : Attribute { public ReactiveAttribute() { } From 7079a46396bf02960803f8fbaee6be3832f6697a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wies=C5=82aw=20S=CC=8Colte=CC=81s?= Date: Wed, 25 Dec 2024 20:26:20 +0100 Subject: [PATCH 09/10] Update --- ...rTests.ClassInGlobalNamespace.verified.txt | 60 +++- ...s.ClassWithAbstractProperties.verified.txt | 60 +++- ...thCustomAccessorAccessibility.verified.txt | 74 ++++- ...mentationAndReactiveAttribute.verified.txt | 29 +- ...ferentPropertyAccessibilities.verified.txt | 102 +++++- ...plicitInterfaceImplementation.verified.txt | 60 +++- ...ithExpressionBodiedProperties.verified.txt | 60 +++- ...straintsAndNullableProperties.verified.txt | 74 ++++- ...ssWithIgnoreReactiveAttribute.verified.txt | 60 +++- ...eratorTests.ClassWithIndexers.verified.txt | 60 +++- ...ests.ClassWithInitOnlySetters.verified.txt | 74 ++++- ...WithMultipleInheritanceLevels.verified.txt | 35 +- ...ithMultipleReactiveAttributes.verified.txt | 4 +- ...Tests.ClassWithNestedGenerics.verified.txt | 74 ++++- ...torTests.ClassWithNestedTypes.verified.txt | 66 +++- ...s.ClassWithNullableProperties.verified.txt | 74 ++++- ...WithPropertyAccessorModifiers.verified.txt | 102 +++++- ...assWithPropertyImplementation.verified.txt | 60 +++- ...AttributeInDifferentNamespace.verified.txt | 128 +++++++- ...WithReactiveObjectInheritance.verified.txt | 4 +- ...s.ClassWithReadOnlyProperties.verified.txt | 66 +++- ...sts.ClassWithStaticProperties.verified.txt | 74 ++++- ...ests.ClassWithTupleProperties.verified.txt | 74 ++++- ...ts.ClassWithVirtualProperties.verified.txt | 74 ++++- ...s.GenericClassWithConstraints.verified.txt | 74 ++++- ...GenericPropertyImplementation.verified.txt | 57 +++- ...enericPropertyWithConstraints.verified.txt | 57 +++- ...opertyWithCustomAccessibility.verified.txt | 71 ++++- ...GenericPropertyWithInitSetter.verified.txt | 71 ++++- ...rtyWithMultipleTypeParameters.verified.txt | 71 ++++- ...enericPropertyWithNestedTypes.verified.txt | 71 ++++- ...nericPropertyWithNullableType.verified.txt | 57 +++- ...ropertyWithReactiveObjectBase.verified.txt | 4 +- ...ricPropertyWithReadOnlyAccess.verified.txt | 63 +++- ...ts.InheritedReactiveAttribute.verified.txt | 48 +-- ...ceWithMixedReactiveAttributes.verified.txt | 48 +-- ...ClassesWithReactiveProperties.verified.txt | 66 +++- ...ultipleClassesWithInheritance.verified.txt | 35 +- ...ts.NestedClassWithInheritance.verified.txt | 38 ++- ...hCustomPropertyImplementation.verified.txt | 66 +++- ...sWithDifferentAccessModifiers.verified.txt | 299 +++++++++++++++++- ...ClassesWithGenericConstraints.verified.txt | 94 +++++- ...sWithInheritanceAndInterfaces.verified.txt | 38 ++- ...ClassesWithInitOnlyProperties.verified.txt | 80 ++++- ...lassesWithMixedReactiveScopes.verified.txt | 69 +++- ...WithReactiveObjectInheritance.verified.txt | 4 +- ...sWithStaticAndInstanceMembers.verified.txt | 80 ++++- ...teClassWithReactiveProperties.verified.txt | 136 +++++++- ...tiveObjectWithMixedProperties.verified.txt | 4 +- ...elReactiveWithCustomAccessors.verified.txt | 4 +- ...yLevelReactiveWithGenericType.verified.txt | 4 +- ...yLevelReactiveWithInheritance.verified.txt | 4 +- ...elReactiveWithMixedProperties.verified.txt | 4 +- ...tDerivedWithComplexProperties.verified.txt | 4 +- ...ivedWithCustomImplementations.verified.txt | 4 +- ...eObjectDerivedWithInheritance.verified.txt | 4 +- ...jectDerivedWithInitProperties.verified.txt | 4 +- ...rivedWithObservableProperties.verified.txt | 4 +- ...eObjectWithClassLevelReactive.verified.txt | 4 +- ...evelReactiveAndIgnoreOverride.verified.txt | 4 +- ...ctWithMixedReactiveProperties.verified.txt | 4 +- ...iveObjectWithNullableGenerics.verified.txt | 4 +- ...ObjectWithPropertyInitializer.verified.txt | 4 +- ...ectWithSingleReactiveProperty.verified.txt | 4 +- ...ctWithoutAnyReactiveAttribute.verified.txt | 4 +- ...pleClassWithReactiveAttribute.verified.txt | 60 +++- ...eratorTests.UseLegacyModeTest.verified.txt | 62 +++- 67 files changed, 3257 insertions(+), 178 deletions(-) diff --git a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassInGlobalNamespace.verified.txt b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassInGlobalNamespace.verified.txt index 4ce9ee1..694c5e0 100644 --- a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassInGlobalNamespace.verified.txt +++ b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassInGlobalNamespace.verified.txt @@ -1,11 +1,67 @@ { Sources: [ + { + FileName: GlobalClass.INPC.g.cs, + Source: +// +#nullable enable + +using System.ComponentModel; +using System.Runtime.CompilerServices; + +public partial class GlobalClass : INotifyPropertyChanged +{ + public event PropertyChangedEventHandler? PropertyChanged; + + protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null) + { + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); + } + + protected virtual void OnPropertyChanged(PropertyChangedEventArgs args) + { + PropertyChanged?.Invoke(this, args); + } +} + + }, + { + FileName: GlobalClass.ReactiveProperties.g.cs, + Source: +// +#nullable enable + +using System.ComponentModel; +using System.Runtime.CompilerServices; + +/// +/// A partial class implementation for GlobalClass. +/// +public partial class GlobalClass +{ + private static readonly PropertyChangedEventArgs _nameChangedEventArgs = new PropertyChangedEventArgs(nameof(Name)); + + public partial string Name + { + get => field; + set + { + if (!Equals(field, value)) + { + field = value; + OnPropertyChanged(_nameChangedEventArgs); + } + } + } +} + + }, { FileName: IgnoreReactiveAttribute.g.cs, Source: using System; -[AttributeUsage(AttributeTargets.Property, Inherited = false, AllowMultiple = false)] +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = false, AllowMultiple = false)] sealed class IgnoreReactiveAttribute : Attribute { public IgnoreReactiveAttribute() { } @@ -16,7 +72,7 @@ sealed class IgnoreReactiveAttribute : Attribute Source: using System; -[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = false, AllowMultiple = false)] +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = true, AllowMultiple = false)] sealed class ReactiveAttribute : Attribute { public ReactiveAttribute() { } diff --git a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithAbstractProperties.verified.txt b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithAbstractProperties.verified.txt index 4ce9ee1..1882feb 100644 --- a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithAbstractProperties.verified.txt +++ b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithAbstractProperties.verified.txt @@ -5,7 +5,7 @@ Source: using System; -[AttributeUsage(AttributeTargets.Property, Inherited = false, AllowMultiple = false)] +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = false, AllowMultiple = false)] sealed class IgnoreReactiveAttribute : Attribute { public IgnoreReactiveAttribute() { } @@ -16,11 +16,67 @@ sealed class IgnoreReactiveAttribute : Attribute Source: using System; -[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = false, AllowMultiple = false)] +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = true, AllowMultiple = false)] sealed class ReactiveAttribute : Attribute { public ReactiveAttribute() { } } + }, + { + FileName: TestClass.INPC.g.cs, + Source: +// +#nullable enable + +using System.ComponentModel; +using System.Runtime.CompilerServices; + +public partial class TestClass : INotifyPropertyChanged +{ + public event PropertyChangedEventHandler? PropertyChanged; + + protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null) + { + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); + } + + protected virtual void OnPropertyChanged(PropertyChangedEventArgs args) + { + PropertyChanged?.Invoke(this, args); + } +} + + }, + { + FileName: TestClass.ReactiveProperties.g.cs, + Source: +// +#nullable enable + +using System.ComponentModel; +using System.Runtime.CompilerServices; + +/// +/// A partial class implementation for TestClass. +/// +public partial class TestClass +{ + private static readonly PropertyChangedEventArgs _concretePropChangedEventArgs = new PropertyChangedEventArgs(nameof(ConcreteProp)); + + public partial string ConcreteProp + { + get => field; + set + { + if (!Equals(field, value)) + { + field = value; + OnPropertyChanged(_concretePropChangedEventArgs); + } + } + } +} + } ], Diagnostics: null diff --git a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithCustomAccessorAccessibility.verified.txt b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithCustomAccessorAccessibility.verified.txt index 4ce9ee1..d28a89e 100644 --- a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithCustomAccessorAccessibility.verified.txt +++ b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithCustomAccessorAccessibility.verified.txt @@ -5,7 +5,7 @@ Source: using System; -[AttributeUsage(AttributeTargets.Property, Inherited = false, AllowMultiple = false)] +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = false, AllowMultiple = false)] sealed class IgnoreReactiveAttribute : Attribute { public IgnoreReactiveAttribute() { } @@ -16,11 +16,81 @@ sealed class IgnoreReactiveAttribute : Attribute Source: using System; -[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = false, AllowMultiple = false)] +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = true, AllowMultiple = false)] sealed class ReactiveAttribute : Attribute { public ReactiveAttribute() { } } + }, + { + FileName: TestClass.INPC.g.cs, + Source: +// +#nullable enable + +using System.ComponentModel; +using System.Runtime.CompilerServices; + +public partial class TestClass : INotifyPropertyChanged +{ + public event PropertyChangedEventHandler? PropertyChanged; + + protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null) + { + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); + } + + protected virtual void OnPropertyChanged(PropertyChangedEventArgs args) + { + PropertyChanged?.Invoke(this, args); + } +} + + }, + { + FileName: TestClass.ReactiveProperties.g.cs, + Source: +// +#nullable enable + +using System.ComponentModel; +using System.Runtime.CompilerServices; + +/// +/// A partial class implementation for TestClass. +/// +public partial class TestClass +{ + private static readonly PropertyChangedEventArgs _nameChangedEventArgs = new PropertyChangedEventArgs(nameof(Name)); + private static readonly PropertyChangedEventArgs _idChangedEventArgs = new PropertyChangedEventArgs(nameof(Id)); + + public partial string Name + { + get => field; + private set + { + if (!Equals(field, value)) + { + field = value; + OnPropertyChanged(_nameChangedEventArgs); + } + } + } + + protected partial string Id + { + private get => field; + set + { + if (!Equals(field, value)) + { + field = value; + OnPropertyChanged(_idChangedEventArgs); + } + } + } +} + } ], Diagnostics: null diff --git a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithCustomPropertyImplementationAndReactiveAttribute.verified.txt b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithCustomPropertyImplementationAndReactiveAttribute.verified.txt index 4ce9ee1..9b77cf4 100644 --- a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithCustomPropertyImplementationAndReactiveAttribute.verified.txt +++ b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithCustomPropertyImplementationAndReactiveAttribute.verified.txt @@ -5,7 +5,7 @@ Source: using System; -[AttributeUsage(AttributeTargets.Property, Inherited = false, AllowMultiple = false)] +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = false, AllowMultiple = false)] sealed class IgnoreReactiveAttribute : Attribute { public IgnoreReactiveAttribute() { } @@ -16,11 +16,36 @@ sealed class IgnoreReactiveAttribute : Attribute Source: using System; -[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = false, AllowMultiple = false)] +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = true, AllowMultiple = false)] sealed class ReactiveAttribute : Attribute { public ReactiveAttribute() { } } + }, + { + FileName: TestClass.INPC.g.cs, + Source: +// +#nullable enable + +using System.ComponentModel; +using System.Runtime.CompilerServices; + +public partial class TestClass : INotifyPropertyChanged +{ + public event PropertyChangedEventHandler? PropertyChanged; + + protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null) + { + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); + } + + protected virtual void OnPropertyChanged(PropertyChangedEventArgs args) + { + PropertyChanged?.Invoke(this, args); + } +} + } ], Diagnostics: null diff --git a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithDifferentPropertyAccessibilities.verified.txt b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithDifferentPropertyAccessibilities.verified.txt index 4ce9ee1..8131374 100644 --- a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithDifferentPropertyAccessibilities.verified.txt +++ b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithDifferentPropertyAccessibilities.verified.txt @@ -5,7 +5,7 @@ Source: using System; -[AttributeUsage(AttributeTargets.Property, Inherited = false, AllowMultiple = false)] +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = false, AllowMultiple = false)] sealed class IgnoreReactiveAttribute : Attribute { public IgnoreReactiveAttribute() { } @@ -16,11 +16,109 @@ sealed class IgnoreReactiveAttribute : Attribute Source: using System; -[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = false, AllowMultiple = false)] +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = true, AllowMultiple = false)] sealed class ReactiveAttribute : Attribute { public ReactiveAttribute() { } } + }, + { + FileName: TestClass.INPC.g.cs, + Source: +// +#nullable enable + +using System.ComponentModel; +using System.Runtime.CompilerServices; + +public partial class TestClass : INotifyPropertyChanged +{ + public event PropertyChangedEventHandler? PropertyChanged; + + protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null) + { + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); + } + + protected virtual void OnPropertyChanged(PropertyChangedEventArgs args) + { + PropertyChanged?.Invoke(this, args); + } +} + + }, + { + FileName: TestClass.ReactiveProperties.g.cs, + Source: +// +#nullable enable + +using System.ComponentModel; +using System.Runtime.CompilerServices; + +/// +/// A partial class implementation for TestClass. +/// +public partial class TestClass +{ + private static readonly PropertyChangedEventArgs _publicPropChangedEventArgs = new PropertyChangedEventArgs(nameof(PublicProp)); + private static readonly PropertyChangedEventArgs _protectedPropChangedEventArgs = new PropertyChangedEventArgs(nameof(ProtectedProp)); + private static readonly PropertyChangedEventArgs _internalPropChangedEventArgs = new PropertyChangedEventArgs(nameof(InternalProp)); + private static readonly PropertyChangedEventArgs _privatePropChangedEventArgs = new PropertyChangedEventArgs(nameof(PrivateProp)); + + public partial string PublicProp + { + get => field; + set + { + if (!Equals(field, value)) + { + field = value; + OnPropertyChanged(_publicPropChangedEventArgs); + } + } + } + + protected partial string ProtectedProp + { + get => field; + set + { + if (!Equals(field, value)) + { + field = value; + OnPropertyChanged(_protectedPropChangedEventArgs); + } + } + } + + internal partial string InternalProp + { + get => field; + set + { + if (!Equals(field, value)) + { + field = value; + OnPropertyChanged(_internalPropChangedEventArgs); + } + } + } + + private partial string PrivateProp + { + get => field; + set + { + if (!Equals(field, value)) + { + field = value; + OnPropertyChanged(_privatePropChangedEventArgs); + } + } + } +} + } ], Diagnostics: null diff --git a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithExplicitInterfaceImplementation.verified.txt b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithExplicitInterfaceImplementation.verified.txt index 4ce9ee1..f55bdd4 100644 --- a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithExplicitInterfaceImplementation.verified.txt +++ b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithExplicitInterfaceImplementation.verified.txt @@ -5,7 +5,7 @@ Source: using System; -[AttributeUsage(AttributeTargets.Property, Inherited = false, AllowMultiple = false)] +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = false, AllowMultiple = false)] sealed class IgnoreReactiveAttribute : Attribute { public IgnoreReactiveAttribute() { } @@ -16,11 +16,67 @@ sealed class IgnoreReactiveAttribute : Attribute Source: using System; -[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = false, AllowMultiple = false)] +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = true, AllowMultiple = false)] sealed class ReactiveAttribute : Attribute { public ReactiveAttribute() { } } + }, + { + FileName: TestClass.INPC.g.cs, + Source: +// +#nullable enable + +using System.ComponentModel; +using System.Runtime.CompilerServices; + +public partial class TestClass : INotifyPropertyChanged +{ + public event PropertyChangedEventHandler? PropertyChanged; + + protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null) + { + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); + } + + protected virtual void OnPropertyChanged(PropertyChangedEventArgs args) + { + PropertyChanged?.Invoke(this, args); + } +} + + }, + { + FileName: TestClass.ReactiveProperties.g.cs, + Source: +// +#nullable enable + +using System.ComponentModel; +using System.Runtime.CompilerServices; + +/// +/// A partial class implementation for TestClass. +/// +public partial class TestClass +{ + private static readonly PropertyChangedEventArgs _publicNameChangedEventArgs = new PropertyChangedEventArgs(nameof(PublicName)); + + public partial string PublicName + { + get => field; + set + { + if (!Equals(field, value)) + { + field = value; + OnPropertyChanged(_publicNameChangedEventArgs); + } + } + } +} + } ], Diagnostics: null diff --git a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithExpressionBodiedProperties.verified.txt b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithExpressionBodiedProperties.verified.txt index 4ce9ee1..2ebc8e4 100644 --- a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithExpressionBodiedProperties.verified.txt +++ b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithExpressionBodiedProperties.verified.txt @@ -5,7 +5,7 @@ Source: using System; -[AttributeUsage(AttributeTargets.Property, Inherited = false, AllowMultiple = false)] +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = false, AllowMultiple = false)] sealed class IgnoreReactiveAttribute : Attribute { public IgnoreReactiveAttribute() { } @@ -16,11 +16,67 @@ sealed class IgnoreReactiveAttribute : Attribute Source: using System; -[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = false, AllowMultiple = false)] +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = true, AllowMultiple = false)] sealed class ReactiveAttribute : Attribute { public ReactiveAttribute() { } } + }, + { + FileName: TestClass.INPC.g.cs, + Source: +// +#nullable enable + +using System.ComponentModel; +using System.Runtime.CompilerServices; + +public partial class TestClass : INotifyPropertyChanged +{ + public event PropertyChangedEventHandler? PropertyChanged; + + protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null) + { + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); + } + + protected virtual void OnPropertyChanged(PropertyChangedEventArgs args) + { + PropertyChanged?.Invoke(this, args); + } +} + + }, + { + FileName: TestClass.ReactiveProperties.g.cs, + Source: +// +#nullable enable + +using System.ComponentModel; +using System.Runtime.CompilerServices; + +/// +/// A partial class implementation for TestClass. +/// +public partial class TestClass +{ + private static readonly PropertyChangedEventArgs _editableNameChangedEventArgs = new PropertyChangedEventArgs(nameof(EditableName)); + + public partial string EditableName + { + get => field; + set + { + if (!Equals(field, value)) + { + field = value; + OnPropertyChanged(_editableNameChangedEventArgs); + } + } + } +} + } ], Diagnostics: null diff --git a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithGenericConstraintsAndNullableProperties.verified.txt b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithGenericConstraintsAndNullableProperties.verified.txt index 4ce9ee1..97e0e4d 100644 --- a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithGenericConstraintsAndNullableProperties.verified.txt +++ b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithGenericConstraintsAndNullableProperties.verified.txt @@ -5,7 +5,7 @@ Source: using System; -[AttributeUsage(AttributeTargets.Property, Inherited = false, AllowMultiple = false)] +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = false, AllowMultiple = false)] sealed class IgnoreReactiveAttribute : Attribute { public IgnoreReactiveAttribute() { } @@ -16,11 +16,81 @@ sealed class IgnoreReactiveAttribute : Attribute Source: using System; -[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = false, AllowMultiple = false)] +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = true, AllowMultiple = false)] sealed class ReactiveAttribute : Attribute { public ReactiveAttribute() { } } + }, + { + FileName: TestClass.INPC.g.cs, + Source: +// +#nullable enable + +using System.ComponentModel; +using System.Runtime.CompilerServices; + +public partial class TestClass : INotifyPropertyChanged where T : class, IDisposable where U : struct, IComparable +{ + public event PropertyChangedEventHandler? PropertyChanged; + + protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null) + { + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); + } + + protected virtual void OnPropertyChanged(PropertyChangedEventArgs args) + { + PropertyChanged?.Invoke(this, args); + } +} + + }, + { + FileName: TestClass.ReactiveProperties.g.cs, + Source: +// +#nullable enable + +using System.ComponentModel; +using System.Runtime.CompilerServices; + +/// +/// A partial class implementation for TestClass{T, U}. +/// +public partial class TestClass where T : class, IDisposable where U : struct, IComparable +{ + private static readonly PropertyChangedEventArgs _nullableRefChangedEventArgs = new PropertyChangedEventArgs(nameof(NullableRef)); + private static readonly PropertyChangedEventArgs _nullableStructChangedEventArgs = new PropertyChangedEventArgs(nameof(NullableStruct)); + + public partial T? NullableRef + { + get => field; + set + { + if (!Equals(field, value)) + { + field = value; + OnPropertyChanged(_nullableRefChangedEventArgs); + } + } + } + + public partial U? NullableStruct + { + get => field; + set + { + if (!Equals(field, value)) + { + field = value; + OnPropertyChanged(_nullableStructChangedEventArgs); + } + } + } +} + } ], Diagnostics: null diff --git a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithIgnoreReactiveAttribute.verified.txt b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithIgnoreReactiveAttribute.verified.txt index 4ce9ee1..a8437a1 100644 --- a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithIgnoreReactiveAttribute.verified.txt +++ b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithIgnoreReactiveAttribute.verified.txt @@ -5,7 +5,7 @@ Source: using System; -[AttributeUsage(AttributeTargets.Property, Inherited = false, AllowMultiple = false)] +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = false, AllowMultiple = false)] sealed class IgnoreReactiveAttribute : Attribute { public IgnoreReactiveAttribute() { } @@ -16,11 +16,67 @@ sealed class IgnoreReactiveAttribute : Attribute Source: using System; -[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = false, AllowMultiple = false)] +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = true, AllowMultiple = false)] sealed class ReactiveAttribute : Attribute { public ReactiveAttribute() { } } + }, + { + FileName: TestClass.INPC.g.cs, + Source: +// +#nullable enable + +using System.ComponentModel; +using System.Runtime.CompilerServices; + +public partial class TestClass : INotifyPropertyChanged +{ + public event PropertyChangedEventHandler? PropertyChanged; + + protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null) + { + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); + } + + protected virtual void OnPropertyChanged(PropertyChangedEventArgs args) + { + PropertyChanged?.Invoke(this, args); + } +} + + }, + { + FileName: TestClass.ReactiveProperties.g.cs, + Source: +// +#nullable enable + +using System.ComponentModel; +using System.Runtime.CompilerServices; + +/// +/// A partial class implementation for TestClass. +/// +public partial class TestClass +{ + private static readonly PropertyChangedEventArgs _includedChangedEventArgs = new PropertyChangedEventArgs(nameof(Included)); + + public partial string Included + { + get => field; + set + { + if (!Equals(field, value)) + { + field = value; + OnPropertyChanged(_includedChangedEventArgs); + } + } + } +} + } ], Diagnostics: null diff --git a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithIndexers.verified.txt b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithIndexers.verified.txt index 4ce9ee1..f55f01e 100644 --- a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithIndexers.verified.txt +++ b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithIndexers.verified.txt @@ -5,7 +5,7 @@ Source: using System; -[AttributeUsage(AttributeTargets.Property, Inherited = false, AllowMultiple = false)] +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = false, AllowMultiple = false)] sealed class IgnoreReactiveAttribute : Attribute { public IgnoreReactiveAttribute() { } @@ -16,11 +16,67 @@ sealed class IgnoreReactiveAttribute : Attribute Source: using System; -[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = false, AllowMultiple = false)] +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = true, AllowMultiple = false)] sealed class ReactiveAttribute : Attribute { public ReactiveAttribute() { } } + }, + { + FileName: TestClass.INPC.g.cs, + Source: +// +#nullable enable + +using System.ComponentModel; +using System.Runtime.CompilerServices; + +public partial class TestClass : INotifyPropertyChanged +{ + public event PropertyChangedEventHandler? PropertyChanged; + + protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null) + { + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); + } + + protected virtual void OnPropertyChanged(PropertyChangedEventArgs args) + { + PropertyChanged?.Invoke(this, args); + } +} + + }, + { + FileName: TestClass.ReactiveProperties.g.cs, + Source: +// +#nullable enable + +using System.ComponentModel; +using System.Runtime.CompilerServices; + +/// +/// A partial class implementation for TestClass. +/// +public partial class TestClass +{ + private static readonly PropertyChangedEventArgs _regularPropChangedEventArgs = new PropertyChangedEventArgs(nameof(RegularProp)); + + public partial string RegularProp + { + get => field; + set + { + if (!Equals(field, value)) + { + field = value; + OnPropertyChanged(_regularPropChangedEventArgs); + } + } + } +} + } ], Diagnostics: null diff --git a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithInitOnlySetters.verified.txt b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithInitOnlySetters.verified.txt index 4ce9ee1..c88282d 100644 --- a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithInitOnlySetters.verified.txt +++ b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithInitOnlySetters.verified.txt @@ -5,7 +5,7 @@ Source: using System; -[AttributeUsage(AttributeTargets.Property, Inherited = false, AllowMultiple = false)] +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = false, AllowMultiple = false)] sealed class IgnoreReactiveAttribute : Attribute { public IgnoreReactiveAttribute() { } @@ -16,11 +16,81 @@ sealed class IgnoreReactiveAttribute : Attribute Source: using System; -[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = false, AllowMultiple = false)] +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = true, AllowMultiple = false)] sealed class ReactiveAttribute : Attribute { public ReactiveAttribute() { } } + }, + { + FileName: TestClass.INPC.g.cs, + Source: +// +#nullable enable + +using System.ComponentModel; +using System.Runtime.CompilerServices; + +public partial class TestClass : INotifyPropertyChanged +{ + public event PropertyChangedEventHandler? PropertyChanged; + + protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null) + { + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); + } + + protected virtual void OnPropertyChanged(PropertyChangedEventArgs args) + { + PropertyChanged?.Invoke(this, args); + } +} + + }, + { + FileName: TestClass.ReactiveProperties.g.cs, + Source: +// +#nullable enable + +using System.ComponentModel; +using System.Runtime.CompilerServices; + +/// +/// A partial class implementation for TestClass. +/// +public partial class TestClass +{ + private static readonly PropertyChangedEventArgs _initOnlyPropChangedEventArgs = new PropertyChangedEventArgs(nameof(InitOnlyProp)); + private static readonly PropertyChangedEventArgs _regularPropChangedEventArgs = new PropertyChangedEventArgs(nameof(RegularProp)); + + public partial string InitOnlyProp + { + get => field; + set + { + if (!Equals(field, value)) + { + field = value; + OnPropertyChanged(_initOnlyPropChangedEventArgs); + } + } + } + + public partial string RegularProp + { + get => field; + set + { + if (!Equals(field, value)) + { + field = value; + OnPropertyChanged(_regularPropChangedEventArgs); + } + } + } +} + } ], Diagnostics: null diff --git a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithMultipleInheritanceLevels.verified.txt b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithMultipleInheritanceLevels.verified.txt index ed47ada..d7ec26b 100644 --- a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithMultipleInheritanceLevels.verified.txt +++ b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithMultipleInheritanceLevels.verified.txt @@ -36,7 +36,7 @@ public partial class Child Source: using System; -[AttributeUsage(AttributeTargets.Property, Inherited = false, AllowMultiple = false)] +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = false, AllowMultiple = false)] sealed class IgnoreReactiveAttribute : Attribute { public IgnoreReactiveAttribute() { } @@ -66,13 +66,44 @@ public partial class Parent : INotifyPropertyChanged } } + }, + { + FileName: Parent.ReactiveProperties.g.cs, + Source: +// +#nullable enable + +using System.ComponentModel; +using System.Runtime.CompilerServices; + +/// +/// A partial class implementation for Parent. +/// +public partial class Parent +{ + private static readonly PropertyChangedEventArgs _parentPropChangedEventArgs = new PropertyChangedEventArgs(nameof(ParentProp)); + + public partial string ParentProp + { + get => field; + set + { + if (!Equals(field, value)) + { + field = value; + OnPropertyChanged(_parentPropChangedEventArgs); + } + } + } +} + }, { FileName: ReactiveAttribute.g.cs, Source: using System; -[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = false, AllowMultiple = false)] +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = true, AllowMultiple = false)] sealed class ReactiveAttribute : Attribute { public ReactiveAttribute() { } diff --git a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithMultipleReactiveAttributes.verified.txt b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithMultipleReactiveAttributes.verified.txt index 925b492..c3045fe 100644 --- a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithMultipleReactiveAttributes.verified.txt +++ b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithMultipleReactiveAttributes.verified.txt @@ -5,7 +5,7 @@ Source: using System; -[AttributeUsage(AttributeTargets.Property, Inherited = false, AllowMultiple = false)] +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = false, AllowMultiple = false)] sealed class IgnoreReactiveAttribute : Attribute { public IgnoreReactiveAttribute() { } @@ -16,7 +16,7 @@ sealed class IgnoreReactiveAttribute : Attribute Source: using System; -[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = false, AllowMultiple = false)] +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = true, AllowMultiple = false)] sealed class ReactiveAttribute : Attribute { public ReactiveAttribute() { } diff --git a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithNestedGenerics.verified.txt b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithNestedGenerics.verified.txt index 4ce9ee1..65a840d 100644 --- a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithNestedGenerics.verified.txt +++ b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithNestedGenerics.verified.txt @@ -5,7 +5,7 @@ Source: using System; -[AttributeUsage(AttributeTargets.Property, Inherited = false, AllowMultiple = false)] +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = false, AllowMultiple = false)] sealed class IgnoreReactiveAttribute : Attribute { public IgnoreReactiveAttribute() { } @@ -16,11 +16,81 @@ sealed class IgnoreReactiveAttribute : Attribute Source: using System; -[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = false, AllowMultiple = false)] +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = true, AllowMultiple = false)] sealed class ReactiveAttribute : Attribute { public ReactiveAttribute() { } } + }, + { + FileName: TestClass.INPC.g.cs, + Source: +// +#nullable enable + +using System.ComponentModel; +using System.Runtime.CompilerServices; + +public partial class TestClass : INotifyPropertyChanged where T : class +{ + public event PropertyChangedEventHandler? PropertyChanged; + + protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null) + { + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); + } + + protected virtual void OnPropertyChanged(PropertyChangedEventArgs args) + { + PropertyChanged?.Invoke(this, args); + } +} + + }, + { + FileName: TestClass.ReactiveProperties.g.cs, + Source: +// +#nullable enable + +using System.ComponentModel; +using System.Runtime.CompilerServices; + +/// +/// A partial class implementation for TestClass{T}. +/// +public partial class TestClass where T : class +{ + private static readonly PropertyChangedEventArgs _complexPropChangedEventArgs = new PropertyChangedEventArgs(nameof(ComplexProp)); + private static readonly PropertyChangedEventArgs _nestedPropChangedEventArgs = new PropertyChangedEventArgs(nameof(NestedProp)); + + public partial List> ComplexProp + { + get => field; + set + { + if (!Equals(field, value)) + { + field = value; + OnPropertyChanged(_complexPropChangedEventArgs); + } + } + } + + public partial Dictionary> NestedProp + { + get => field; + set + { + if (!Equals(field, value)) + { + field = value; + OnPropertyChanged(_nestedPropChangedEventArgs); + } + } + } +} + } ], Diagnostics: null diff --git a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithNestedTypes.verified.txt b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithNestedTypes.verified.txt index 4ce9ee1..939d069 100644 --- a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithNestedTypes.verified.txt +++ b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithNestedTypes.verified.txt @@ -5,18 +5,80 @@ Source: using System; -[AttributeUsage(AttributeTargets.Property, Inherited = false, AllowMultiple = false)] +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = false, AllowMultiple = false)] sealed class IgnoreReactiveAttribute : Attribute { public IgnoreReactiveAttribute() { } } + }, + { + FileName: OuterClass.InnerClass.INPC.g.cs, + Source: +// +#nullable enable + +using System.ComponentModel; +using System.Runtime.CompilerServices; + +public partial class OuterClass +{ + public partial class InnerClass : INotifyPropertyChanged + { + public event PropertyChangedEventHandler? PropertyChanged; + + protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null) + { + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); + } + + protected virtual void OnPropertyChanged(PropertyChangedEventArgs args) + { + PropertyChanged?.Invoke(this, args); + } + } +} + + }, + { + FileName: OuterClass.InnerClass.ReactiveProperties.g.cs, + Source: +// +#nullable enable + +using System.ComponentModel; +using System.Runtime.CompilerServices; + +public partial class OuterClass +{ + /// + /// A partial class implementation for OuterClass.InnerClass. + /// + public partial class InnerClass + { + private static readonly PropertyChangedEventArgs _nameChangedEventArgs = new PropertyChangedEventArgs(nameof(Name)); + + public partial string Name + { + get => field; + set + { + if (!Equals(field, value)) + { + field = value; + OnPropertyChanged(_nameChangedEventArgs); + } + } + } + } +} + }, { FileName: ReactiveAttribute.g.cs, Source: using System; -[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = false, AllowMultiple = false)] +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = true, AllowMultiple = false)] sealed class ReactiveAttribute : Attribute { public ReactiveAttribute() { } diff --git a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithNullableProperties.verified.txt b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithNullableProperties.verified.txt index 4ce9ee1..77ed6cf 100644 --- a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithNullableProperties.verified.txt +++ b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithNullableProperties.verified.txt @@ -5,7 +5,7 @@ Source: using System; -[AttributeUsage(AttributeTargets.Property, Inherited = false, AllowMultiple = false)] +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = false, AllowMultiple = false)] sealed class IgnoreReactiveAttribute : Attribute { public IgnoreReactiveAttribute() { } @@ -16,11 +16,81 @@ sealed class IgnoreReactiveAttribute : Attribute Source: using System; -[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = false, AllowMultiple = false)] +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = true, AllowMultiple = false)] sealed class ReactiveAttribute : Attribute { public ReactiveAttribute() { } } + }, + { + FileName: TestClass.INPC.g.cs, + Source: +// +#nullable enable + +using System.ComponentModel; +using System.Runtime.CompilerServices; + +public partial class TestClass : INotifyPropertyChanged +{ + public event PropertyChangedEventHandler? PropertyChanged; + + protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null) + { + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); + } + + protected virtual void OnPropertyChanged(PropertyChangedEventArgs args) + { + PropertyChanged?.Invoke(this, args); + } +} + + }, + { + FileName: TestClass.ReactiveProperties.g.cs, + Source: +// +#nullable enable + +using System.ComponentModel; +using System.Runtime.CompilerServices; + +/// +/// A partial class implementation for TestClass. +/// +public partial class TestClass +{ + private static readonly PropertyChangedEventArgs _nullableRefChangedEventArgs = new PropertyChangedEventArgs(nameof(NullableRef)); + private static readonly PropertyChangedEventArgs _nullableValueChangedEventArgs = new PropertyChangedEventArgs(nameof(NullableValue)); + + public partial string? NullableRef + { + get => field; + set + { + if (!Equals(field, value)) + { + field = value; + OnPropertyChanged(_nullableRefChangedEventArgs); + } + } + } + + public partial int? NullableValue + { + get => field; + set + { + if (!Equals(field, value)) + { + field = value; + OnPropertyChanged(_nullableValueChangedEventArgs); + } + } + } +} + } ], Diagnostics: null diff --git a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithPropertyAccessorModifiers.verified.txt b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithPropertyAccessorModifiers.verified.txt index 4ce9ee1..5e28feb 100644 --- a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithPropertyAccessorModifiers.verified.txt +++ b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithPropertyAccessorModifiers.verified.txt @@ -5,7 +5,7 @@ Source: using System; -[AttributeUsage(AttributeTargets.Property, Inherited = false, AllowMultiple = false)] +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = false, AllowMultiple = false)] sealed class IgnoreReactiveAttribute : Attribute { public IgnoreReactiveAttribute() { } @@ -16,11 +16,109 @@ sealed class IgnoreReactiveAttribute : Attribute Source: using System; -[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = false, AllowMultiple = false)] +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = true, AllowMultiple = false)] sealed class ReactiveAttribute : Attribute { public ReactiveAttribute() { } } + }, + { + FileName: TestClass.INPC.g.cs, + Source: +// +#nullable enable + +using System.ComponentModel; +using System.Runtime.CompilerServices; + +public partial class TestClass : INotifyPropertyChanged +{ + public event PropertyChangedEventHandler? PropertyChanged; + + protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null) + { + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); + } + + protected virtual void OnPropertyChanged(PropertyChangedEventArgs args) + { + PropertyChanged?.Invoke(this, args); + } +} + + }, + { + FileName: TestClass.ReactiveProperties.g.cs, + Source: +// +#nullable enable + +using System.ComponentModel; +using System.Runtime.CompilerServices; + +/// +/// A partial class implementation for TestClass. +/// +public partial class TestClass +{ + private static readonly PropertyChangedEventArgs _propWithPrivateSetChangedEventArgs = new PropertyChangedEventArgs(nameof(PropWithPrivateSet)); + private static readonly PropertyChangedEventArgs _propWithProtectedGetChangedEventArgs = new PropertyChangedEventArgs(nameof(PropWithProtectedGet)); + private static readonly PropertyChangedEventArgs _propWithInternalSetChangedEventArgs = new PropertyChangedEventArgs(nameof(PropWithInternalSet)); + private static readonly PropertyChangedEventArgs _propWithProtectedInternalSetChangedEventArgs = new PropertyChangedEventArgs(nameof(PropWithProtectedInternalSet)); + + public partial string PropWithPrivateSet + { + get => field; + private set + { + if (!Equals(field, value)) + { + field = value; + OnPropertyChanged(_propWithPrivateSetChangedEventArgs); + } + } + } + + protected partial string PropWithProtectedGet + { + private get => field; + set + { + if (!Equals(field, value)) + { + field = value; + OnPropertyChanged(_propWithProtectedGetChangedEventArgs); + } + } + } + + internal partial string PropWithInternalSet + { + get => field; + set + { + if (!Equals(field, value)) + { + field = value; + OnPropertyChanged(_propWithInternalSetChangedEventArgs); + } + } + } + + public partial string PropWithProtectedInternalSet + { + get => field; + protected internal set + { + if (!Equals(field, value)) + { + field = value; + OnPropertyChanged(_propWithProtectedInternalSetChangedEventArgs); + } + } + } +} + } ], Diagnostics: null diff --git a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithPropertyImplementation.verified.txt b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithPropertyImplementation.verified.txt index 4ce9ee1..bd99298 100644 --- a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithPropertyImplementation.verified.txt +++ b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithPropertyImplementation.verified.txt @@ -5,7 +5,7 @@ Source: using System; -[AttributeUsage(AttributeTargets.Property, Inherited = false, AllowMultiple = false)] +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = false, AllowMultiple = false)] sealed class IgnoreReactiveAttribute : Attribute { public IgnoreReactiveAttribute() { } @@ -16,11 +16,67 @@ sealed class IgnoreReactiveAttribute : Attribute Source: using System; -[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = false, AllowMultiple = false)] +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = true, AllowMultiple = false)] sealed class ReactiveAttribute : Attribute { public ReactiveAttribute() { } } + }, + { + FileName: TestClass.INPC.g.cs, + Source: +// +#nullable enable + +using System.ComponentModel; +using System.Runtime.CompilerServices; + +public partial class TestClass : INotifyPropertyChanged +{ + public event PropertyChangedEventHandler? PropertyChanged; + + protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null) + { + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); + } + + protected virtual void OnPropertyChanged(PropertyChangedEventArgs args) + { + PropertyChanged?.Invoke(this, args); + } +} + + }, + { + FileName: TestClass.ReactiveProperties.g.cs, + Source: +// +#nullable enable + +using System.ComponentModel; +using System.Runtime.CompilerServices; + +/// +/// A partial class implementation for TestClass. +/// +public partial class TestClass +{ + private static readonly PropertyChangedEventArgs _notImplementedChangedEventArgs = new PropertyChangedEventArgs(nameof(NotImplemented)); + + public partial string NotImplemented + { + get => field; + set + { + if (!Equals(field, value)) + { + field = value; + OnPropertyChanged(_notImplementedChangedEventArgs); + } + } + } +} + } ], Diagnostics: null diff --git a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithReactiveAttributeInDifferentNamespace.verified.txt b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithReactiveAttributeInDifferentNamespace.verified.txt index 4ce9ee1..69738f6 100644 --- a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithReactiveAttributeInDifferentNamespace.verified.txt +++ b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithReactiveAttributeInDifferentNamespace.verified.txt @@ -1,11 +1,73 @@ { Sources: [ + { + FileName: First.TestClass.INPC.g.cs, + Source: +// +#nullable enable + +using System.ComponentModel; +using System.Runtime.CompilerServices; + +namespace First +{ + public partial class TestClass : INotifyPropertyChanged + { + public event PropertyChangedEventHandler? PropertyChanged; + + protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null) + { + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); + } + + protected virtual void OnPropertyChanged(PropertyChangedEventArgs args) + { + PropertyChanged?.Invoke(this, args); + } + } +} + + }, + { + FileName: First.TestClass.ReactiveProperties.g.cs, + Source: +// +#nullable enable + +using System.ComponentModel; +using System.Runtime.CompilerServices; + +namespace First +{ + /// + /// A partial class implementation for First.TestClass. + /// + public partial class TestClass + { + private static readonly PropertyChangedEventArgs _nameChangedEventArgs = new PropertyChangedEventArgs(nameof(Name)); + + public partial string Name + { + get => field; + set + { + if (!Equals(field, value)) + { + field = value; + OnPropertyChanged(_nameChangedEventArgs); + } + } + } + } +} + + }, { FileName: IgnoreReactiveAttribute.g.cs, Source: using System; -[AttributeUsage(AttributeTargets.Property, Inherited = false, AllowMultiple = false)] +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = false, AllowMultiple = false)] sealed class IgnoreReactiveAttribute : Attribute { public IgnoreReactiveAttribute() { } @@ -16,11 +78,73 @@ sealed class IgnoreReactiveAttribute : Attribute Source: using System; -[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = false, AllowMultiple = false)] +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = true, AllowMultiple = false)] sealed class ReactiveAttribute : Attribute { public ReactiveAttribute() { } } + }, + { + FileName: Second.TestClass.INPC.g.cs, + Source: +// +#nullable enable + +using System.ComponentModel; +using System.Runtime.CompilerServices; + +namespace Second +{ + public partial class TestClass : INotifyPropertyChanged + { + public event PropertyChangedEventHandler? PropertyChanged; + + protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null) + { + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); + } + + protected virtual void OnPropertyChanged(PropertyChangedEventArgs args) + { + PropertyChanged?.Invoke(this, args); + } + } +} + + }, + { + FileName: Second.TestClass.ReactiveProperties.g.cs, + Source: +// +#nullable enable + +using System.ComponentModel; +using System.Runtime.CompilerServices; + +namespace Second +{ + /// + /// A partial class implementation for Second.TestClass. + /// + public partial class TestClass + { + private static readonly PropertyChangedEventArgs _nameChangedEventArgs = new PropertyChangedEventArgs(nameof(Name)); + + public partial string Name + { + get => field; + set + { + if (!Equals(field, value)) + { + field = value; + OnPropertyChanged(_nameChangedEventArgs); + } + } + } + } +} + } ], Diagnostics: null diff --git a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithReactiveObjectInheritance.verified.txt b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithReactiveObjectInheritance.verified.txt index d80a3b6..73297b3 100644 --- a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithReactiveObjectInheritance.verified.txt +++ b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithReactiveObjectInheritance.verified.txt @@ -5,7 +5,7 @@ Source: using System; -[AttributeUsage(AttributeTargets.Property, Inherited = false, AllowMultiple = false)] +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = false, AllowMultiple = false)] sealed class IgnoreReactiveAttribute : Attribute { public IgnoreReactiveAttribute() { } @@ -16,7 +16,7 @@ sealed class IgnoreReactiveAttribute : Attribute Source: using System; -[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = false, AllowMultiple = false)] +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = true, AllowMultiple = false)] sealed class ReactiveAttribute : Attribute { public ReactiveAttribute() { } diff --git a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithReadOnlyProperties.verified.txt b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithReadOnlyProperties.verified.txt index 4ce9ee1..1dbb3b0 100644 --- a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithReadOnlyProperties.verified.txt +++ b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithReadOnlyProperties.verified.txt @@ -5,7 +5,7 @@ Source: using System; -[AttributeUsage(AttributeTargets.Property, Inherited = false, AllowMultiple = false)] +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = false, AllowMultiple = false)] sealed class IgnoreReactiveAttribute : Attribute { public IgnoreReactiveAttribute() { } @@ -16,11 +16,73 @@ sealed class IgnoreReactiveAttribute : Attribute Source: using System; -[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = false, AllowMultiple = false)] +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = true, AllowMultiple = false)] sealed class ReactiveAttribute : Attribute { public ReactiveAttribute() { } } + }, + { + FileName: TestClass.INPC.g.cs, + Source: +// +#nullable enable + +using System.ComponentModel; +using System.Runtime.CompilerServices; + +public partial class TestClass : INotifyPropertyChanged +{ + public event PropertyChangedEventHandler? PropertyChanged; + + protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null) + { + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); + } + + protected virtual void OnPropertyChanged(PropertyChangedEventArgs args) + { + PropertyChanged?.Invoke(this, args); + } +} + + }, + { + FileName: TestClass.ReactiveProperties.g.cs, + Source: +// +#nullable enable + +using System.ComponentModel; +using System.Runtime.CompilerServices; + +/// +/// A partial class implementation for TestClass. +/// +public partial class TestClass +{ + private static readonly PropertyChangedEventArgs _readOnlyChangedEventArgs = new PropertyChangedEventArgs(nameof(ReadOnly)); + private static readonly PropertyChangedEventArgs _readWriteChangedEventArgs = new PropertyChangedEventArgs(nameof(ReadWrite)); + + public partial string ReadOnly + { + get => field; + } + + public partial string ReadWrite + { + get => field; + set + { + if (!Equals(field, value)) + { + field = value; + OnPropertyChanged(_readWriteChangedEventArgs); + } + } + } +} + } ], Diagnostics: null diff --git a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithStaticProperties.verified.txt b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithStaticProperties.verified.txt index 4ce9ee1..99f3c0d 100644 --- a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithStaticProperties.verified.txt +++ b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithStaticProperties.verified.txt @@ -5,7 +5,7 @@ Source: using System; -[AttributeUsage(AttributeTargets.Property, Inherited = false, AllowMultiple = false)] +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = false, AllowMultiple = false)] sealed class IgnoreReactiveAttribute : Attribute { public IgnoreReactiveAttribute() { } @@ -16,11 +16,81 @@ sealed class IgnoreReactiveAttribute : Attribute Source: using System; -[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = false, AllowMultiple = false)] +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = true, AllowMultiple = false)] sealed class ReactiveAttribute : Attribute { public ReactiveAttribute() { } } + }, + { + FileName: TestClass.INPC.g.cs, + Source: +// +#nullable enable + +using System.ComponentModel; +using System.Runtime.CompilerServices; + +public partial class TestClass : INotifyPropertyChanged +{ + public event PropertyChangedEventHandler? PropertyChanged; + + protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null) + { + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); + } + + protected virtual void OnPropertyChanged(PropertyChangedEventArgs args) + { + PropertyChanged?.Invoke(this, args); + } +} + + }, + { + FileName: TestClass.ReactiveProperties.g.cs, + Source: +// +#nullable enable + +using System.ComponentModel; +using System.Runtime.CompilerServices; + +/// +/// A partial class implementation for TestClass. +/// +public partial class TestClass +{ + private static readonly PropertyChangedEventArgs _staticPropChangedEventArgs = new PropertyChangedEventArgs(nameof(StaticProp)); + private static readonly PropertyChangedEventArgs _instancePropChangedEventArgs = new PropertyChangedEventArgs(nameof(InstanceProp)); + + public partial string StaticProp + { + get => field; + set + { + if (!Equals(field, value)) + { + field = value; + OnPropertyChanged(_staticPropChangedEventArgs); + } + } + } + + public partial string InstanceProp + { + get => field; + set + { + if (!Equals(field, value)) + { + field = value; + OnPropertyChanged(_instancePropChangedEventArgs); + } + } + } +} + } ], Diagnostics: null diff --git a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithTupleProperties.verified.txt b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithTupleProperties.verified.txt index 4ce9ee1..0449c97 100644 --- a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithTupleProperties.verified.txt +++ b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithTupleProperties.verified.txt @@ -5,7 +5,7 @@ Source: using System; -[AttributeUsage(AttributeTargets.Property, Inherited = false, AllowMultiple = false)] +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = false, AllowMultiple = false)] sealed class IgnoreReactiveAttribute : Attribute { public IgnoreReactiveAttribute() { } @@ -16,11 +16,81 @@ sealed class IgnoreReactiveAttribute : Attribute Source: using System; -[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = false, AllowMultiple = false)] +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = true, AllowMultiple = false)] sealed class ReactiveAttribute : Attribute { public ReactiveAttribute() { } } + }, + { + FileName: TestClass.INPC.g.cs, + Source: +// +#nullable enable + +using System.ComponentModel; +using System.Runtime.CompilerServices; + +public partial class TestClass : INotifyPropertyChanged +{ + public event PropertyChangedEventHandler? PropertyChanged; + + protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null) + { + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); + } + + protected virtual void OnPropertyChanged(PropertyChangedEventArgs args) + { + PropertyChanged?.Invoke(this, args); + } +} + + }, + { + FileName: TestClass.ReactiveProperties.g.cs, + Source: +// +#nullable enable + +using System.ComponentModel; +using System.Runtime.CompilerServices; + +/// +/// A partial class implementation for TestClass. +/// +public partial class TestClass +{ + private static readonly PropertyChangedEventArgs _personInfoChangedEventArgs = new PropertyChangedEventArgs(nameof(PersonInfo)); + private static readonly PropertyChangedEventArgs _pointChangedEventArgs = new PropertyChangedEventArgs(nameof(Point)); + + public partial (string Name, int Age) PersonInfo + { + get => field; + set + { + if (!Equals(field, value)) + { + field = value; + OnPropertyChanged(_personInfoChangedEventArgs); + } + } + } + + public partial (int X, int Y, string Label) Point + { + get => field; + set + { + if (!Equals(field, value)) + { + field = value; + OnPropertyChanged(_pointChangedEventArgs); + } + } + } +} + } ], Diagnostics: null diff --git a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithVirtualProperties.verified.txt b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithVirtualProperties.verified.txt index 4ce9ee1..96ddd99 100644 --- a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithVirtualProperties.verified.txt +++ b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ClassWithVirtualProperties.verified.txt @@ -5,7 +5,7 @@ Source: using System; -[AttributeUsage(AttributeTargets.Property, Inherited = false, AllowMultiple = false)] +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = false, AllowMultiple = false)] sealed class IgnoreReactiveAttribute : Attribute { public IgnoreReactiveAttribute() { } @@ -16,11 +16,81 @@ sealed class IgnoreReactiveAttribute : Attribute Source: using System; -[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = false, AllowMultiple = false)] +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = true, AllowMultiple = false)] sealed class ReactiveAttribute : Attribute { public ReactiveAttribute() { } } + }, + { + FileName: TestClass.INPC.g.cs, + Source: +// +#nullable enable + +using System.ComponentModel; +using System.Runtime.CompilerServices; + +public partial class TestClass : INotifyPropertyChanged +{ + public event PropertyChangedEventHandler? PropertyChanged; + + protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null) + { + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); + } + + protected virtual void OnPropertyChanged(PropertyChangedEventArgs args) + { + PropertyChanged?.Invoke(this, args); + } +} + + }, + { + FileName: TestClass.ReactiveProperties.g.cs, + Source: +// +#nullable enable + +using System.ComponentModel; +using System.Runtime.CompilerServices; + +/// +/// A partial class implementation for TestClass. +/// +public partial class TestClass +{ + private static readonly PropertyChangedEventArgs _virtualPropChangedEventArgs = new PropertyChangedEventArgs(nameof(VirtualProp)); + private static readonly PropertyChangedEventArgs _nonVirtualPropChangedEventArgs = new PropertyChangedEventArgs(nameof(NonVirtualProp)); + + public partial string VirtualProp + { + get => field; + set + { + if (!Equals(field, value)) + { + field = value; + OnPropertyChanged(_virtualPropChangedEventArgs); + } + } + } + + public partial string NonVirtualProp + { + get => field; + set + { + if (!Equals(field, value)) + { + field = value; + OnPropertyChanged(_nonVirtualPropChangedEventArgs); + } + } + } +} + } ], Diagnostics: null diff --git a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.GenericClassWithConstraints.verified.txt b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.GenericClassWithConstraints.verified.txt index 4ce9ee1..d624782 100644 --- a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.GenericClassWithConstraints.verified.txt +++ b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.GenericClassWithConstraints.verified.txt @@ -5,7 +5,7 @@ Source: using System; -[AttributeUsage(AttributeTargets.Property, Inherited = false, AllowMultiple = false)] +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = false, AllowMultiple = false)] sealed class IgnoreReactiveAttribute : Attribute { public IgnoreReactiveAttribute() { } @@ -16,11 +16,81 @@ sealed class IgnoreReactiveAttribute : Attribute Source: using System; -[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = false, AllowMultiple = false)] +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = true, AllowMultiple = false)] sealed class ReactiveAttribute : Attribute { public ReactiveAttribute() { } } + }, + { + FileName: TestClass.INPC.g.cs, + Source: +// +#nullable enable + +using System.ComponentModel; +using System.Runtime.CompilerServices; + +public partial class TestClass : INotifyPropertyChanged where T : class, new() where U : struct +{ + public event PropertyChangedEventHandler? PropertyChanged; + + protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null) + { + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); + } + + protected virtual void OnPropertyChanged(PropertyChangedEventArgs args) + { + PropertyChanged?.Invoke(this, args); + } +} + + }, + { + FileName: TestClass.ReactiveProperties.g.cs, + Source: +// +#nullable enable + +using System.ComponentModel; +using System.Runtime.CompilerServices; + +/// +/// A partial class implementation for TestClass{T, U}. +/// +public partial class TestClass where T : class, new() where U : struct +{ + private static readonly PropertyChangedEventArgs _referenceChangedEventArgs = new PropertyChangedEventArgs(nameof(Reference)); + private static readonly PropertyChangedEventArgs _valueChangedEventArgs = new PropertyChangedEventArgs(nameof(Value)); + + public partial T Reference + { + get => field; + set + { + if (!Equals(field, value)) + { + field = value; + OnPropertyChanged(_referenceChangedEventArgs); + } + } + } + + public partial U Value + { + get => field; + set + { + if (!Equals(field, value)) + { + field = value; + OnPropertyChanged(_valueChangedEventArgs); + } + } + } +} + } ], Diagnostics: null diff --git a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.GenericPropertyImplementation.verified.txt b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.GenericPropertyImplementation.verified.txt index 4ce9ee1..f3d0bba 100644 --- a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.GenericPropertyImplementation.verified.txt +++ b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.GenericPropertyImplementation.verified.txt @@ -1,11 +1,64 @@ { Sources: [ + { + FileName: GenericViewModel.INPC.g.cs, + Source: +// +#nullable enable + +using System.ComponentModel; +using System.Runtime.CompilerServices; + +internal partial class GenericViewModel : INotifyPropertyChanged +{ + public event PropertyChangedEventHandler? PropertyChanged; + + protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null) + { + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); + } + + protected virtual void OnPropertyChanged(PropertyChangedEventArgs args) + { + PropertyChanged?.Invoke(this, args); + } +} + + }, + { + FileName: GenericViewModel.ReactiveProperties.g.cs, + Source: +// +#nullable enable + +using System.ComponentModel; +using System.Runtime.CompilerServices; + +internal partial class GenericViewModel +{ + private static readonly PropertyChangedEventArgs _valueChangedEventArgs = new PropertyChangedEventArgs(nameof(Value)); + + public partial T Value + { + get => field; + set + { + if (!Equals(field, value)) + { + field = value; + OnPropertyChanged(_valueChangedEventArgs); + } + } + } +} + + }, { FileName: IgnoreReactiveAttribute.g.cs, Source: using System; -[AttributeUsage(AttributeTargets.Property, Inherited = false, AllowMultiple = false)] +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = false, AllowMultiple = false)] sealed class IgnoreReactiveAttribute : Attribute { public IgnoreReactiveAttribute() { } @@ -16,7 +69,7 @@ sealed class IgnoreReactiveAttribute : Attribute Source: using System; -[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = false, AllowMultiple = false)] +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = true, AllowMultiple = false)] sealed class ReactiveAttribute : Attribute { public ReactiveAttribute() { } diff --git a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.GenericPropertyWithConstraints.verified.txt b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.GenericPropertyWithConstraints.verified.txt index 4ce9ee1..94547a6 100644 --- a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.GenericPropertyWithConstraints.verified.txt +++ b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.GenericPropertyWithConstraints.verified.txt @@ -1,11 +1,64 @@ { Sources: [ + { + FileName: GenericViewModel.INPC.g.cs, + Source: +// +#nullable enable + +using System.ComponentModel; +using System.Runtime.CompilerServices; + +internal partial class GenericViewModel : INotifyPropertyChanged where T : class, new() +{ + public event PropertyChangedEventHandler? PropertyChanged; + + protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null) + { + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); + } + + protected virtual void OnPropertyChanged(PropertyChangedEventArgs args) + { + PropertyChanged?.Invoke(this, args); + } +} + + }, + { + FileName: GenericViewModel.ReactiveProperties.g.cs, + Source: +// +#nullable enable + +using System.ComponentModel; +using System.Runtime.CompilerServices; + +internal partial class GenericViewModel where T : class, new() +{ + private static readonly PropertyChangedEventArgs _valueChangedEventArgs = new PropertyChangedEventArgs(nameof(Value)); + + public partial T Value + { + get => field; + set + { + if (!Equals(field, value)) + { + field = value; + OnPropertyChanged(_valueChangedEventArgs); + } + } + } +} + + }, { FileName: IgnoreReactiveAttribute.g.cs, Source: using System; -[AttributeUsage(AttributeTargets.Property, Inherited = false, AllowMultiple = false)] +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = false, AllowMultiple = false)] sealed class IgnoreReactiveAttribute : Attribute { public IgnoreReactiveAttribute() { } @@ -16,7 +69,7 @@ sealed class IgnoreReactiveAttribute : Attribute Source: using System; -[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = false, AllowMultiple = false)] +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = true, AllowMultiple = false)] sealed class ReactiveAttribute : Attribute { public ReactiveAttribute() { } diff --git a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.GenericPropertyWithCustomAccessibility.verified.txt b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.GenericPropertyWithCustomAccessibility.verified.txt index 4ce9ee1..92205cc 100644 --- a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.GenericPropertyWithCustomAccessibility.verified.txt +++ b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.GenericPropertyWithCustomAccessibility.verified.txt @@ -1,11 +1,78 @@ { Sources: [ + { + FileName: GenericViewModel.INPC.g.cs, + Source: +// +#nullable enable + +using System.ComponentModel; +using System.Runtime.CompilerServices; + +internal partial class GenericViewModel : INotifyPropertyChanged +{ + public event PropertyChangedEventHandler? PropertyChanged; + + protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null) + { + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); + } + + protected virtual void OnPropertyChanged(PropertyChangedEventArgs args) + { + PropertyChanged?.Invoke(this, args); + } +} + + }, + { + FileName: GenericViewModel.ReactiveProperties.g.cs, + Source: +// +#nullable enable + +using System.ComponentModel; +using System.Runtime.CompilerServices; + +internal partial class GenericViewModel +{ + private static readonly PropertyChangedEventArgs _valueChangedEventArgs = new PropertyChangedEventArgs(nameof(Value)); + private static readonly PropertyChangedEventArgs _protectedValueChangedEventArgs = new PropertyChangedEventArgs(nameof(ProtectedValue)); + + public partial T Value + { + get => field; + private set + { + if (!Equals(field, value)) + { + field = value; + OnPropertyChanged(_valueChangedEventArgs); + } + } + } + + protected partial T ProtectedValue + { + get => field; + set + { + if (!Equals(field, value)) + { + field = value; + OnPropertyChanged(_protectedValueChangedEventArgs); + } + } + } +} + + }, { FileName: IgnoreReactiveAttribute.g.cs, Source: using System; -[AttributeUsage(AttributeTargets.Property, Inherited = false, AllowMultiple = false)] +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = false, AllowMultiple = false)] sealed class IgnoreReactiveAttribute : Attribute { public IgnoreReactiveAttribute() { } @@ -16,7 +83,7 @@ sealed class IgnoreReactiveAttribute : Attribute Source: using System; -[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = false, AllowMultiple = false)] +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = true, AllowMultiple = false)] sealed class ReactiveAttribute : Attribute { public ReactiveAttribute() { } diff --git a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.GenericPropertyWithInitSetter.verified.txt b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.GenericPropertyWithInitSetter.verified.txt index 4ce9ee1..c964ba1 100644 --- a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.GenericPropertyWithInitSetter.verified.txt +++ b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.GenericPropertyWithInitSetter.verified.txt @@ -1,11 +1,78 @@ { Sources: [ + { + FileName: GenericViewModel.INPC.g.cs, + Source: +// +#nullable enable + +using System.ComponentModel; +using System.Runtime.CompilerServices; + +internal partial class GenericViewModel : INotifyPropertyChanged +{ + public event PropertyChangedEventHandler? PropertyChanged; + + protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null) + { + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); + } + + protected virtual void OnPropertyChanged(PropertyChangedEventArgs args) + { + PropertyChanged?.Invoke(this, args); + } +} + + }, + { + FileName: GenericViewModel.ReactiveProperties.g.cs, + Source: +// +#nullable enable + +using System.ComponentModel; +using System.Runtime.CompilerServices; + +internal partial class GenericViewModel +{ + private static readonly PropertyChangedEventArgs _initValueChangedEventArgs = new PropertyChangedEventArgs(nameof(InitValue)); + private static readonly PropertyChangedEventArgs _regularValueChangedEventArgs = new PropertyChangedEventArgs(nameof(RegularValue)); + + public partial T InitValue + { + get => field; + set + { + if (!Equals(field, value)) + { + field = value; + OnPropertyChanged(_initValueChangedEventArgs); + } + } + } + + public partial T RegularValue + { + get => field; + set + { + if (!Equals(field, value)) + { + field = value; + OnPropertyChanged(_regularValueChangedEventArgs); + } + } + } +} + + }, { FileName: IgnoreReactiveAttribute.g.cs, Source: using System; -[AttributeUsage(AttributeTargets.Property, Inherited = false, AllowMultiple = false)] +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = false, AllowMultiple = false)] sealed class IgnoreReactiveAttribute : Attribute { public IgnoreReactiveAttribute() { } @@ -16,7 +83,7 @@ sealed class IgnoreReactiveAttribute : Attribute Source: using System; -[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = false, AllowMultiple = false)] +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = true, AllowMultiple = false)] sealed class ReactiveAttribute : Attribute { public ReactiveAttribute() { } diff --git a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.GenericPropertyWithMultipleTypeParameters.verified.txt b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.GenericPropertyWithMultipleTypeParameters.verified.txt index 4ce9ee1..83700db 100644 --- a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.GenericPropertyWithMultipleTypeParameters.verified.txt +++ b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.GenericPropertyWithMultipleTypeParameters.verified.txt @@ -1,11 +1,78 @@ { Sources: [ + { + FileName: GenericViewModel.INPC.g.cs, + Source: +// +#nullable enable + +using System.ComponentModel; +using System.Runtime.CompilerServices; + +internal partial class GenericViewModel : INotifyPropertyChanged where T : class where U : struct +{ + public event PropertyChangedEventHandler? PropertyChanged; + + protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null) + { + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); + } + + protected virtual void OnPropertyChanged(PropertyChangedEventArgs args) + { + PropertyChanged?.Invoke(this, args); + } +} + + }, + { + FileName: GenericViewModel.ReactiveProperties.g.cs, + Source: +// +#nullable enable + +using System.ComponentModel; +using System.Runtime.CompilerServices; + +internal partial class GenericViewModel where T : class where U : struct +{ + private static readonly PropertyChangedEventArgs _refValueChangedEventArgs = new PropertyChangedEventArgs(nameof(RefValue)); + private static readonly PropertyChangedEventArgs _valueTypeChangedEventArgs = new PropertyChangedEventArgs(nameof(ValueType)); + + public partial T? RefValue + { + get => field; + set + { + if (!Equals(field, value)) + { + field = value; + OnPropertyChanged(_refValueChangedEventArgs); + } + } + } + + public partial U ValueType + { + get => field; + set + { + if (!Equals(field, value)) + { + field = value; + OnPropertyChanged(_valueTypeChangedEventArgs); + } + } + } +} + + }, { FileName: IgnoreReactiveAttribute.g.cs, Source: using System; -[AttributeUsage(AttributeTargets.Property, Inherited = false, AllowMultiple = false)] +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = false, AllowMultiple = false)] sealed class IgnoreReactiveAttribute : Attribute { public IgnoreReactiveAttribute() { } @@ -16,7 +83,7 @@ sealed class IgnoreReactiveAttribute : Attribute Source: using System; -[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = false, AllowMultiple = false)] +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = true, AllowMultiple = false)] sealed class ReactiveAttribute : Attribute { public ReactiveAttribute() { } diff --git a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.GenericPropertyWithNestedTypes.verified.txt b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.GenericPropertyWithNestedTypes.verified.txt index 4ce9ee1..f6e45ca 100644 --- a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.GenericPropertyWithNestedTypes.verified.txt +++ b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.GenericPropertyWithNestedTypes.verified.txt @@ -1,11 +1,78 @@ { Sources: [ + { + FileName: GenericViewModel.INPC.g.cs, + Source: +// +#nullable enable + +using System.ComponentModel; +using System.Runtime.CompilerServices; + +internal partial class GenericViewModel : INotifyPropertyChanged +{ + public event PropertyChangedEventHandler? PropertyChanged; + + protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null) + { + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); + } + + protected virtual void OnPropertyChanged(PropertyChangedEventArgs args) + { + PropertyChanged?.Invoke(this, args); + } +} + + }, + { + FileName: GenericViewModel.ReactiveProperties.g.cs, + Source: +// +#nullable enable + +using System.ComponentModel; +using System.Runtime.CompilerServices; + +internal partial class GenericViewModel +{ + private static readonly PropertyChangedEventArgs _listValueChangedEventArgs = new PropertyChangedEventArgs(nameof(ListValue)); + private static readonly PropertyChangedEventArgs _dictValueChangedEventArgs = new PropertyChangedEventArgs(nameof(DictValue)); + + public partial List ListValue + { + get => field; + set + { + if (!Equals(field, value)) + { + field = value; + OnPropertyChanged(_listValueChangedEventArgs); + } + } + } + + public partial Dictionary DictValue + { + get => field; + set + { + if (!Equals(field, value)) + { + field = value; + OnPropertyChanged(_dictValueChangedEventArgs); + } + } + } +} + + }, { FileName: IgnoreReactiveAttribute.g.cs, Source: using System; -[AttributeUsage(AttributeTargets.Property, Inherited = false, AllowMultiple = false)] +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = false, AllowMultiple = false)] sealed class IgnoreReactiveAttribute : Attribute { public IgnoreReactiveAttribute() { } @@ -16,7 +83,7 @@ sealed class IgnoreReactiveAttribute : Attribute Source: using System; -[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = false, AllowMultiple = false)] +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = true, AllowMultiple = false)] sealed class ReactiveAttribute : Attribute { public ReactiveAttribute() { } diff --git a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.GenericPropertyWithNullableType.verified.txt b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.GenericPropertyWithNullableType.verified.txt index 4ce9ee1..f06abd8 100644 --- a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.GenericPropertyWithNullableType.verified.txt +++ b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.GenericPropertyWithNullableType.verified.txt @@ -1,11 +1,64 @@ { Sources: [ + { + FileName: GenericViewModel.INPC.g.cs, + Source: +// +#nullable enable + +using System.ComponentModel; +using System.Runtime.CompilerServices; + +internal partial class GenericViewModel : INotifyPropertyChanged where T : class +{ + public event PropertyChangedEventHandler? PropertyChanged; + + protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null) + { + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); + } + + protected virtual void OnPropertyChanged(PropertyChangedEventArgs args) + { + PropertyChanged?.Invoke(this, args); + } +} + + }, + { + FileName: GenericViewModel.ReactiveProperties.g.cs, + Source: +// +#nullable enable + +using System.ComponentModel; +using System.Runtime.CompilerServices; + +internal partial class GenericViewModel where T : class +{ + private static readonly PropertyChangedEventArgs _valueChangedEventArgs = new PropertyChangedEventArgs(nameof(Value)); + + public partial T? Value + { + get => field; + set + { + if (!Equals(field, value)) + { + field = value; + OnPropertyChanged(_valueChangedEventArgs); + } + } + } +} + + }, { FileName: IgnoreReactiveAttribute.g.cs, Source: using System; -[AttributeUsage(AttributeTargets.Property, Inherited = false, AllowMultiple = false)] +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = false, AllowMultiple = false)] sealed class IgnoreReactiveAttribute : Attribute { public IgnoreReactiveAttribute() { } @@ -16,7 +69,7 @@ sealed class IgnoreReactiveAttribute : Attribute Source: using System; -[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = false, AllowMultiple = false)] +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = true, AllowMultiple = false)] sealed class ReactiveAttribute : Attribute { public ReactiveAttribute() { } diff --git a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.GenericPropertyWithReactiveObjectBase.verified.txt b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.GenericPropertyWithReactiveObjectBase.verified.txt index 5bc9f4a..13146b0 100644 --- a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.GenericPropertyWithReactiveObjectBase.verified.txt +++ b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.GenericPropertyWithReactiveObjectBase.verified.txt @@ -23,7 +23,7 @@ internal partial class GenericViewModel where T : class Source: using System; -[AttributeUsage(AttributeTargets.Property, Inherited = false, AllowMultiple = false)] +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = false, AllowMultiple = false)] sealed class IgnoreReactiveAttribute : Attribute { public IgnoreReactiveAttribute() { } @@ -34,7 +34,7 @@ sealed class IgnoreReactiveAttribute : Attribute Source: using System; -[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = false, AllowMultiple = false)] +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = true, AllowMultiple = false)] sealed class ReactiveAttribute : Attribute { public ReactiveAttribute() { } diff --git a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.GenericPropertyWithReadOnlyAccess.verified.txt b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.GenericPropertyWithReadOnlyAccess.verified.txt index 4ce9ee1..aae2175 100644 --- a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.GenericPropertyWithReadOnlyAccess.verified.txt +++ b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.GenericPropertyWithReadOnlyAccess.verified.txt @@ -1,11 +1,70 @@ { Sources: [ + { + FileName: GenericViewModel.INPC.g.cs, + Source: +// +#nullable enable + +using System.ComponentModel; +using System.Runtime.CompilerServices; + +internal partial class GenericViewModel : INotifyPropertyChanged +{ + public event PropertyChangedEventHandler? PropertyChanged; + + protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null) + { + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); + } + + protected virtual void OnPropertyChanged(PropertyChangedEventArgs args) + { + PropertyChanged?.Invoke(this, args); + } +} + + }, + { + FileName: GenericViewModel.ReactiveProperties.g.cs, + Source: +// +#nullable enable + +using System.ComponentModel; +using System.Runtime.CompilerServices; + +internal partial class GenericViewModel +{ + private static readonly PropertyChangedEventArgs _valueChangedEventArgs = new PropertyChangedEventArgs(nameof(Value)); + private static readonly PropertyChangedEventArgs _readWriteValueChangedEventArgs = new PropertyChangedEventArgs(nameof(ReadWriteValue)); + + public partial T Value + { + get => field; + } + + public partial T ReadWriteValue + { + get => field; + set + { + if (!Equals(field, value)) + { + field = value; + OnPropertyChanged(_readWriteValueChangedEventArgs); + } + } + } +} + + }, { FileName: IgnoreReactiveAttribute.g.cs, Source: using System; -[AttributeUsage(AttributeTargets.Property, Inherited = false, AllowMultiple = false)] +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = false, AllowMultiple = false)] sealed class IgnoreReactiveAttribute : Attribute { public IgnoreReactiveAttribute() { } @@ -16,7 +75,7 @@ sealed class IgnoreReactiveAttribute : Attribute Source: using System; -[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = false, AllowMultiple = false)] +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = true, AllowMultiple = false)] sealed class ReactiveAttribute : Attribute { public ReactiveAttribute() { } diff --git a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.InheritedReactiveAttribute.verified.txt b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.InheritedReactiveAttribute.verified.txt index 04688ee..e4f04ae 100644 --- a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.InheritedReactiveAttribute.verified.txt +++ b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.InheritedReactiveAttribute.verified.txt @@ -26,7 +26,7 @@ public partial class BaseViewModel : INotifyPropertyChanged }, { - FileName: DerivedViewModel.ReactiveProperties.g.cs, + FileName: BaseViewModel.ReactiveProperties.g.cs, Source: // #nullable enable @@ -35,13 +35,13 @@ using System.ComponentModel; using System.Runtime.CompilerServices; /// -/// A partial class implementation for DerivedViewModel. +/// A partial class implementation for BaseViewModel. /// -public partial class DerivedViewModel +public partial class BaseViewModel { - private static readonly PropertyChangedEventArgs _derivedPropChangedEventArgs = new PropertyChangedEventArgs(nameof(DerivedProp)); + private static readonly PropertyChangedEventArgs _basePropChangedEventArgs = new PropertyChangedEventArgs(nameof(BaseProp)); - public partial string DerivedProp + public partial string BaseProp { get => field; set @@ -49,7 +49,7 @@ public partial class DerivedViewModel if (!Equals(field, value)) { field = value; - OnPropertyChanged(_derivedPropChangedEventArgs); + OnPropertyChanged(_basePropChangedEventArgs); } } } @@ -57,18 +57,7 @@ public partial class DerivedViewModel }, { - FileName: IgnoreReactiveAttribute.g.cs, - Source: -using System; - -[AttributeUsage(AttributeTargets.Property, Inherited = false, AllowMultiple = false)] -sealed class IgnoreReactiveAttribute : Attribute -{ - public IgnoreReactiveAttribute() { } -} - }, - { - FileName: NonReactiveViewModel.ReactiveProperties.g.cs, + FileName: DerivedViewModel.ReactiveProperties.g.cs, Source: // #nullable enable @@ -77,13 +66,13 @@ using System.ComponentModel; using System.Runtime.CompilerServices; /// -/// A partial class implementation for NonReactiveViewModel. +/// A partial class implementation for DerivedViewModel. /// -public partial class NonReactiveViewModel +public partial class DerivedViewModel { - private static readonly PropertyChangedEventArgs _ignoredPropChangedEventArgs = new PropertyChangedEventArgs(nameof(IgnoredProp)); + private static readonly PropertyChangedEventArgs _derivedPropChangedEventArgs = new PropertyChangedEventArgs(nameof(DerivedProp)); - public partial string IgnoredProp + public partial string DerivedProp { get => field; set @@ -91,7 +80,7 @@ public partial class NonReactiveViewModel if (!Equals(field, value)) { field = value; - OnPropertyChanged(_ignoredPropChangedEventArgs); + OnPropertyChanged(_derivedPropChangedEventArgs); } } } @@ -99,11 +88,22 @@ public partial class NonReactiveViewModel }, { - FileName: ReactiveAttribute.g.cs, + FileName: IgnoreReactiveAttribute.g.cs, Source: using System; [AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = false, AllowMultiple = false)] +sealed class IgnoreReactiveAttribute : Attribute +{ + public IgnoreReactiveAttribute() { } +} + }, + { + FileName: ReactiveAttribute.g.cs, + Source: +using System; + +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = true, AllowMultiple = false)] sealed class ReactiveAttribute : Attribute { public ReactiveAttribute() { } diff --git a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.MultiLevelInheritanceWithMixedReactiveAttributes.verified.txt b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.MultiLevelInheritanceWithMixedReactiveAttributes.verified.txt index 82ff38f..773cd9e 100644 --- a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.MultiLevelInheritanceWithMixedReactiveAttributes.verified.txt +++ b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.MultiLevelInheritanceWithMixedReactiveAttributes.verified.txt @@ -26,18 +26,7 @@ public partial class BaseViewModel : INotifyPropertyChanged }, { - FileName: IgnoreReactiveAttribute.g.cs, - Source: -using System; - -[AttributeUsage(AttributeTargets.Property, Inherited = false, AllowMultiple = false)] -sealed class IgnoreReactiveAttribute : Attribute -{ - public IgnoreReactiveAttribute() { } -} - }, - { - FileName: MiddleViewModel.ReactiveProperties.g.cs, + FileName: BaseViewModel.ReactiveProperties.g.cs, Source: // #nullable enable @@ -46,13 +35,13 @@ using System.ComponentModel; using System.Runtime.CompilerServices; /// -/// A partial class implementation for MiddleViewModel. +/// A partial class implementation for BaseViewModel. /// -public partial class MiddleViewModel +public partial class BaseViewModel { - private static readonly PropertyChangedEventArgs _middlePropChangedEventArgs = new PropertyChangedEventArgs(nameof(MiddleProp)); + private static readonly PropertyChangedEventArgs _basePropChangedEventArgs = new PropertyChangedEventArgs(nameof(BaseProp)); - public partial string MiddleProp + public partial string BaseProp { get => field; set @@ -60,7 +49,7 @@ public partial class MiddleViewModel if (!Equals(field, value)) { field = value; - OnPropertyChanged(_middlePropChangedEventArgs); + OnPropertyChanged(_basePropChangedEventArgs); } } } @@ -68,7 +57,18 @@ public partial class MiddleViewModel }, { - FileName: NonReactiveViewModel.ReactiveProperties.g.cs, + FileName: IgnoreReactiveAttribute.g.cs, + Source: +using System; + +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = false, AllowMultiple = false)] +sealed class IgnoreReactiveAttribute : Attribute +{ + public IgnoreReactiveAttribute() { } +} + }, + { + FileName: MiddleViewModel.ReactiveProperties.g.cs, Source: // #nullable enable @@ -77,13 +77,13 @@ using System.ComponentModel; using System.Runtime.CompilerServices; /// -/// A partial class implementation for NonReactiveViewModel. +/// A partial class implementation for MiddleViewModel. /// -public partial class NonReactiveViewModel +public partial class MiddleViewModel { - private static readonly PropertyChangedEventArgs _nonReactivePropChangedEventArgs = new PropertyChangedEventArgs(nameof(NonReactiveProp)); + private static readonly PropertyChangedEventArgs _middlePropChangedEventArgs = new PropertyChangedEventArgs(nameof(MiddleProp)); - public partial string NonReactiveProp + public partial string MiddleProp { get => field; set @@ -91,7 +91,7 @@ public partial class NonReactiveViewModel if (!Equals(field, value)) { field = value; - OnPropertyChanged(_nonReactivePropChangedEventArgs); + OnPropertyChanged(_middlePropChangedEventArgs); } } } @@ -103,7 +103,7 @@ public partial class NonReactiveViewModel Source: using System; -[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = false, AllowMultiple = false)] +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = true, AllowMultiple = false)] sealed class ReactiveAttribute : Attribute { public ReactiveAttribute() { } diff --git a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.MultiLevelNestedClassesWithReactiveProperties.verified.txt b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.MultiLevelNestedClassesWithReactiveProperties.verified.txt index 4ce9ee1..8e2601f 100644 --- a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.MultiLevelNestedClassesWithReactiveProperties.verified.txt +++ b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.MultiLevelNestedClassesWithReactiveProperties.verified.txt @@ -5,18 +5,80 @@ Source: using System; -[AttributeUsage(AttributeTargets.Property, Inherited = false, AllowMultiple = false)] +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = false, AllowMultiple = false)] sealed class IgnoreReactiveAttribute : Attribute { public IgnoreReactiveAttribute() { } } + }, + { + FileName: Level1.Level2.INPC.g.cs, + Source: +// +#nullable enable + +using System.ComponentModel; +using System.Runtime.CompilerServices; + +public partial class Level1 +{ + public partial class Level2 : INotifyPropertyChanged + { + public event PropertyChangedEventHandler? PropertyChanged; + + protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null) + { + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); + } + + protected virtual void OnPropertyChanged(PropertyChangedEventArgs args) + { + PropertyChanged?.Invoke(this, args); + } + } +} + + }, + { + FileName: Level1.Level2.ReactiveProperties.g.cs, + Source: +// +#nullable enable + +using System.ComponentModel; +using System.Runtime.CompilerServices; + +public partial class Level1 +{ + /// + /// A partial class implementation for Level1.Level2. + /// + public partial class Level2 + { + private static readonly PropertyChangedEventArgs _level2PropChangedEventArgs = new PropertyChangedEventArgs(nameof(Level2Prop)); + + public partial string Level2Prop + { + get => field; + set + { + if (!Equals(field, value)) + { + field = value; + OnPropertyChanged(_level2PropChangedEventArgs); + } + } + } + } +} + }, { FileName: ReactiveAttribute.g.cs, Source: using System; -[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = false, AllowMultiple = false)] +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = true, AllowMultiple = false)] sealed class ReactiveAttribute : Attribute { public ReactiveAttribute() { } diff --git a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.MultipleClassesWithInheritance.verified.txt b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.MultipleClassesWithInheritance.verified.txt index 0661312..6a820f2 100644 --- a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.MultipleClassesWithInheritance.verified.txt +++ b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.MultipleClassesWithInheritance.verified.txt @@ -24,6 +24,37 @@ public partial class BaseClass : INotifyPropertyChanged } } + }, + { + FileName: BaseClass.ReactiveProperties.g.cs, + Source: +// +#nullable enable + +using System.ComponentModel; +using System.Runtime.CompilerServices; + +/// +/// A partial class implementation for BaseClass. +/// +public partial class BaseClass +{ + private static readonly PropertyChangedEventArgs _basePropChangedEventArgs = new PropertyChangedEventArgs(nameof(BaseProp)); + + public partial string BaseProp + { + get => field; + set + { + if (!Equals(field, value)) + { + field = value; + OnPropertyChanged(_basePropChangedEventArgs); + } + } + } +} + }, { FileName: DerivedClass.ReactiveProperties.g.cs, @@ -61,7 +92,7 @@ public partial class DerivedClass Source: using System; -[AttributeUsage(AttributeTargets.Property, Inherited = false, AllowMultiple = false)] +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = false, AllowMultiple = false)] sealed class IgnoreReactiveAttribute : Attribute { public IgnoreReactiveAttribute() { } @@ -72,7 +103,7 @@ sealed class IgnoreReactiveAttribute : Attribute Source: using System; -[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = false, AllowMultiple = false)] +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = true, AllowMultiple = false)] sealed class ReactiveAttribute : Attribute { public ReactiveAttribute() { } diff --git a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.NestedClassWithInheritance.verified.txt b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.NestedClassWithInheritance.verified.txt index fac403e..3025e5d 100644 --- a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.NestedClassWithInheritance.verified.txt +++ b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.NestedClassWithInheritance.verified.txt @@ -5,7 +5,7 @@ Source: using System; -[AttributeUsage(AttributeTargets.Property, Inherited = false, AllowMultiple = false)] +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = false, AllowMultiple = false)] sealed class IgnoreReactiveAttribute : Attribute { public IgnoreReactiveAttribute() { } @@ -38,6 +38,40 @@ public partial class OuterClass } } + }, + { + FileName: OuterClass.InnerBase.ReactiveProperties.g.cs, + Source: +// +#nullable enable + +using System.ComponentModel; +using System.Runtime.CompilerServices; + +public partial class OuterClass +{ + /// + /// A partial class implementation for OuterClass.InnerBase. + /// + public partial class InnerBase + { + private static readonly PropertyChangedEventArgs _basePropChangedEventArgs = new PropertyChangedEventArgs(nameof(BaseProp)); + + public partial string BaseProp + { + get => field; + set + { + if (!Equals(field, value)) + { + field = value; + OnPropertyChanged(_basePropChangedEventArgs); + } + } + } + } +} + }, { FileName: OuterClass.InnerDerived.ReactiveProperties.g.cs, @@ -78,7 +112,7 @@ public partial class OuterClass Source: using System; -[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = false, AllowMultiple = false)] +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = true, AllowMultiple = false)] sealed class ReactiveAttribute : Attribute { public ReactiveAttribute() { } diff --git a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.NestedClassesWithCustomPropertyImplementation.verified.txt b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.NestedClassesWithCustomPropertyImplementation.verified.txt index 4ce9ee1..dfb0cc3 100644 --- a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.NestedClassesWithCustomPropertyImplementation.verified.txt +++ b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.NestedClassesWithCustomPropertyImplementation.verified.txt @@ -1,11 +1,73 @@ { Sources: [ + { + FileName: Container.Nested.INPC.g.cs, + Source: +// +#nullable enable + +using System.ComponentModel; +using System.Runtime.CompilerServices; + +public partial class Container +{ + public partial class Nested : INotifyPropertyChanged + { + public event PropertyChangedEventHandler? PropertyChanged; + + protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null) + { + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); + } + + protected virtual void OnPropertyChanged(PropertyChangedEventArgs args) + { + PropertyChanged?.Invoke(this, args); + } + } +} + + }, + { + FileName: Container.Nested.ReactiveProperties.g.cs, + Source: +// +#nullable enable + +using System.ComponentModel; +using System.Runtime.CompilerServices; + +public partial class Container +{ + /// + /// A partial class implementation for Container.Nested. + /// + public partial class Nested + { + private static readonly PropertyChangedEventArgs _regularPropChangedEventArgs = new PropertyChangedEventArgs(nameof(RegularProp)); + + public partial string RegularProp + { + get => field; + set + { + if (!Equals(field, value)) + { + field = value; + OnPropertyChanged(_regularPropChangedEventArgs); + } + } + } + } +} + + }, { FileName: IgnoreReactiveAttribute.g.cs, Source: using System; -[AttributeUsage(AttributeTargets.Property, Inherited = false, AllowMultiple = false)] +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = false, AllowMultiple = false)] sealed class IgnoreReactiveAttribute : Attribute { public IgnoreReactiveAttribute() { } @@ -16,7 +78,7 @@ sealed class IgnoreReactiveAttribute : Attribute Source: using System; -[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = false, AllowMultiple = false)] +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = true, AllowMultiple = false)] sealed class ReactiveAttribute : Attribute { public ReactiveAttribute() { } diff --git a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.NestedClassesWithDifferentAccessModifiers.verified.txt b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.NestedClassesWithDifferentAccessModifiers.verified.txt index 4ce9ee1..7e543ea 100644 --- a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.NestedClassesWithDifferentAccessModifiers.verified.txt +++ b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.NestedClassesWithDifferentAccessModifiers.verified.txt @@ -1,11 +1,306 @@ { Sources: [ + { + FileName: Container.INPC.g.cs, + Source: +// +#nullable enable + +using System.ComponentModel; +using System.Runtime.CompilerServices; + +public partial class Container : INotifyPropertyChanged +{ + public event PropertyChangedEventHandler? PropertyChanged; + + protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null) + { + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); + } + + protected virtual void OnPropertyChanged(PropertyChangedEventArgs args) + { + PropertyChanged?.Invoke(this, args); + } +} + + }, + { + FileName: Container.Internal.INPC.g.cs, + Source: +// +#nullable enable + +using System.ComponentModel; +using System.Runtime.CompilerServices; + +public partial class Container +{ + internal partial class Internal : INotifyPropertyChanged + { + public event PropertyChangedEventHandler? PropertyChanged; + + protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null) + { + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); + } + + protected virtual void OnPropertyChanged(PropertyChangedEventArgs args) + { + PropertyChanged?.Invoke(this, args); + } + } +} + + }, + { + FileName: Container.Internal.ReactiveProperties.g.cs, + Source: +// +#nullable enable + +using System.ComponentModel; +using System.Runtime.CompilerServices; + +public partial class Container +{ + internal partial class Internal + { + private static readonly PropertyChangedEventArgs _internalPropChangedEventArgs = new PropertyChangedEventArgs(nameof(InternalProp)); + + public partial string InternalProp + { + get => field; + set + { + if (!Equals(field, value)) + { + field = value; + OnPropertyChanged(_internalPropChangedEventArgs); + } + } + } + } +} + + }, + { + FileName: Container.Private.INPC.g.cs, + Source: +// +#nullable enable + +using System.ComponentModel; +using System.Runtime.CompilerServices; + +public partial class Container +{ + private partial class Private : INotifyPropertyChanged + { + public event PropertyChangedEventHandler? PropertyChanged; + + protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null) + { + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); + } + + protected virtual void OnPropertyChanged(PropertyChangedEventArgs args) + { + PropertyChanged?.Invoke(this, args); + } + } +} + + }, + { + FileName: Container.Private.ReactiveProperties.g.cs, + Source: +// +#nullable enable + +using System.ComponentModel; +using System.Runtime.CompilerServices; + +public partial class Container +{ + private partial class Private + { + private static readonly PropertyChangedEventArgs _privatePropChangedEventArgs = new PropertyChangedEventArgs(nameof(PrivateProp)); + + public partial string PrivateProp + { + get => field; + set + { + if (!Equals(field, value)) + { + field = value; + OnPropertyChanged(_privatePropChangedEventArgs); + } + } + } + } +} + + }, + { + FileName: Container.Protected.INPC.g.cs, + Source: +// +#nullable enable + +using System.ComponentModel; +using System.Runtime.CompilerServices; + +public partial class Container +{ + protected partial class Protected : INotifyPropertyChanged + { + public event PropertyChangedEventHandler? PropertyChanged; + + protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null) + { + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); + } + + protected virtual void OnPropertyChanged(PropertyChangedEventArgs args) + { + PropertyChanged?.Invoke(this, args); + } + } +} + + }, + { + FileName: Container.Protected.ReactiveProperties.g.cs, + Source: +// +#nullable enable + +using System.ComponentModel; +using System.Runtime.CompilerServices; + +public partial class Container +{ + protected partial class Protected + { + private static readonly PropertyChangedEventArgs _protectedPropChangedEventArgs = new PropertyChangedEventArgs(nameof(ProtectedProp)); + + public partial string ProtectedProp + { + get => field; + set + { + if (!Equals(field, value)) + { + field = value; + OnPropertyChanged(_protectedPropChangedEventArgs); + } + } + } + } +} + + }, + { + FileName: Container.Public.INPC.g.cs, + Source: +// +#nullable enable + +using System.ComponentModel; +using System.Runtime.CompilerServices; + +public partial class Container +{ + public partial class Public : INotifyPropertyChanged + { + public event PropertyChangedEventHandler? PropertyChanged; + + protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null) + { + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); + } + + protected virtual void OnPropertyChanged(PropertyChangedEventArgs args) + { + PropertyChanged?.Invoke(this, args); + } + } +} + + }, + { + FileName: Container.Public.ReactiveProperties.g.cs, + Source: +// +#nullable enable + +using System.ComponentModel; +using System.Runtime.CompilerServices; + +public partial class Container +{ + /// + /// A partial class implementation for Container.Public. + /// + public partial class Public + { + private static readonly PropertyChangedEventArgs _publicPropChangedEventArgs = new PropertyChangedEventArgs(nameof(PublicProp)); + + public partial string PublicProp + { + get => field; + set + { + if (!Equals(field, value)) + { + field = value; + OnPropertyChanged(_publicPropChangedEventArgs); + } + } + } + } +} + + }, + { + FileName: Container.ReactiveProperties.g.cs, + Source: +// +#nullable enable + +using System.ComponentModel; +using System.Runtime.CompilerServices; + +/// +/// A partial class implementation for Container. +/// +public partial class Container +{ + private static readonly PropertyChangedEventArgs _containerPropChangedEventArgs = new PropertyChangedEventArgs(nameof(ContainerProp)); + + public partial string ContainerProp + { + get => field; + set + { + if (!Equals(field, value)) + { + field = value; + OnPropertyChanged(_containerPropChangedEventArgs); + } + } + } +} + + }, { FileName: IgnoreReactiveAttribute.g.cs, Source: using System; -[AttributeUsage(AttributeTargets.Property, Inherited = false, AllowMultiple = false)] +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = false, AllowMultiple = false)] sealed class IgnoreReactiveAttribute : Attribute { public IgnoreReactiveAttribute() { } @@ -16,7 +311,7 @@ sealed class IgnoreReactiveAttribute : Attribute Source: using System; -[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = false, AllowMultiple = false)] +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = true, AllowMultiple = false)] sealed class ReactiveAttribute : Attribute { public ReactiveAttribute() { } diff --git a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.NestedClassesWithGenericConstraints.verified.txt b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.NestedClassesWithGenericConstraints.verified.txt index 4ce9ee1..d4d9bdd 100644 --- a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.NestedClassesWithGenericConstraints.verified.txt +++ b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.NestedClassesWithGenericConstraints.verified.txt @@ -1,11 +1,101 @@ { Sources: [ + { + FileName: Container.Nested.INPC.g.cs, + Source: +// +#nullable enable + +using System.ComponentModel; +using System.Runtime.CompilerServices; + +public partial class Container +{ + public partial class Nested : INotifyPropertyChanged where U : struct + { + public event PropertyChangedEventHandler? PropertyChanged; + + protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null) + { + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); + } + + protected virtual void OnPropertyChanged(PropertyChangedEventArgs args) + { + PropertyChanged?.Invoke(this, args); + } + } +} + + }, + { + FileName: Container.Nested.ReactiveProperties.g.cs, + Source: +// +#nullable enable + +using System.ComponentModel; +using System.Runtime.CompilerServices; + +public partial class Container +{ + /// + /// A partial class implementation for Container{T}.Nested{U}. + /// + public partial class Nested where U : struct + { + private static readonly PropertyChangedEventArgs _refPropChangedEventArgs = new PropertyChangedEventArgs(nameof(RefProp)); + private static readonly PropertyChangedEventArgs _valuePropChangedEventArgs = new PropertyChangedEventArgs(nameof(ValueProp)); + private static readonly PropertyChangedEventArgs _complexPropChangedEventArgs = new PropertyChangedEventArgs(nameof(ComplexProp)); + + public partial T? RefProp + { + get => field; + set + { + if (!Equals(field, value)) + { + field = value; + OnPropertyChanged(_refPropChangedEventArgs); + } + } + } + + public partial U ValueProp + { + get => field; + set + { + if (!Equals(field, value)) + { + field = value; + OnPropertyChanged(_valuePropChangedEventArgs); + } + } + } + + public partial Dictionary> ComplexProp + { + get => field; + set + { + if (!Equals(field, value)) + { + field = value; + OnPropertyChanged(_complexPropChangedEventArgs); + } + } + } + } +} + + }, { FileName: IgnoreReactiveAttribute.g.cs, Source: using System; -[AttributeUsage(AttributeTargets.Property, Inherited = false, AllowMultiple = false)] +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = false, AllowMultiple = false)] sealed class IgnoreReactiveAttribute : Attribute { public IgnoreReactiveAttribute() { } @@ -16,7 +106,7 @@ sealed class IgnoreReactiveAttribute : Attribute Source: using System; -[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = false, AllowMultiple = false)] +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = true, AllowMultiple = false)] sealed class ReactiveAttribute : Attribute { public ReactiveAttribute() { } diff --git a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.NestedClassesWithInheritanceAndInterfaces.verified.txt b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.NestedClassesWithInheritanceAndInterfaces.verified.txt index eb919f5..d18d1b2 100644 --- a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.NestedClassesWithInheritanceAndInterfaces.verified.txt +++ b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.NestedClassesWithInheritanceAndInterfaces.verified.txt @@ -27,6 +27,40 @@ public partial class Container } } + }, + { + FileName: Container.NestedBase.ReactiveProperties.g.cs, + Source: +// +#nullable enable + +using System.ComponentModel; +using System.Runtime.CompilerServices; + +public partial class Container +{ + /// + /// A partial class implementation for Container.NestedBase. + /// + public partial class NestedBase + { + private static readonly PropertyChangedEventArgs _virtualPropChangedEventArgs = new PropertyChangedEventArgs(nameof(VirtualProp)); + + public partial string VirtualProp + { + get => field; + set + { + if (!Equals(field, value)) + { + field = value; + OnPropertyChanged(_virtualPropChangedEventArgs); + } + } + } + } +} + }, { FileName: Container.NestedDerived.ReactiveProperties.g.cs, @@ -81,7 +115,7 @@ public partial class Container Source: using System; -[AttributeUsage(AttributeTargets.Property, Inherited = false, AllowMultiple = false)] +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = false, AllowMultiple = false)] sealed class IgnoreReactiveAttribute : Attribute { public IgnoreReactiveAttribute() { } @@ -92,7 +126,7 @@ sealed class IgnoreReactiveAttribute : Attribute Source: using System; -[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = false, AllowMultiple = false)] +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = true, AllowMultiple = false)] sealed class ReactiveAttribute : Attribute { public ReactiveAttribute() { } diff --git a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.NestedClassesWithInitOnlyProperties.verified.txt b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.NestedClassesWithInitOnlyProperties.verified.txt index 4ce9ee1..d3983ac 100644 --- a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.NestedClassesWithInitOnlyProperties.verified.txt +++ b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.NestedClassesWithInitOnlyProperties.verified.txt @@ -1,11 +1,87 @@ { Sources: [ + { + FileName: Container.Nested.INPC.g.cs, + Source: +// +#nullable enable + +using System.ComponentModel; +using System.Runtime.CompilerServices; + +public partial class Container +{ + public partial class Nested : INotifyPropertyChanged + { + public event PropertyChangedEventHandler? PropertyChanged; + + protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null) + { + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); + } + + protected virtual void OnPropertyChanged(PropertyChangedEventArgs args) + { + PropertyChanged?.Invoke(this, args); + } + } +} + + }, + { + FileName: Container.Nested.ReactiveProperties.g.cs, + Source: +// +#nullable enable + +using System.ComponentModel; +using System.Runtime.CompilerServices; + +public partial class Container +{ + /// + /// A partial class implementation for Container.Nested. + /// + public partial class Nested + { + private static readonly PropertyChangedEventArgs _regularPropChangedEventArgs = new PropertyChangedEventArgs(nameof(RegularProp)); + private static readonly PropertyChangedEventArgs _initOnlyPropChangedEventArgs = new PropertyChangedEventArgs(nameof(InitOnlyProp)); + + public partial string RegularProp + { + get => field; + set + { + if (!Equals(field, value)) + { + field = value; + OnPropertyChanged(_regularPropChangedEventArgs); + } + } + } + + public partial string InitOnlyProp + { + get => field; + set + { + if (!Equals(field, value)) + { + field = value; + OnPropertyChanged(_initOnlyPropChangedEventArgs); + } + } + } + } +} + + }, { FileName: IgnoreReactiveAttribute.g.cs, Source: using System; -[AttributeUsage(AttributeTargets.Property, Inherited = false, AllowMultiple = false)] +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = false, AllowMultiple = false)] sealed class IgnoreReactiveAttribute : Attribute { public IgnoreReactiveAttribute() { } @@ -16,7 +92,7 @@ sealed class IgnoreReactiveAttribute : Attribute Source: using System; -[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = false, AllowMultiple = false)] +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = true, AllowMultiple = false)] sealed class ReactiveAttribute : Attribute { public ReactiveAttribute() { } diff --git a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.NestedClassesWithMixedReactiveScopes.verified.txt b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.NestedClassesWithMixedReactiveScopes.verified.txt index 9f37bb4..af33232 100644 --- a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.NestedClassesWithMixedReactiveScopes.verified.txt +++ b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.NestedClassesWithMixedReactiveScopes.verified.txt @@ -114,13 +114,78 @@ public partial class Container } } + }, + { + FileName: Container.ReactiveNested.ReactiveProperties.g.cs, + Source: +// +#nullable enable + +using System.ComponentModel; +using System.Runtime.CompilerServices; + +public partial class Container +{ + /// + /// A partial class implementation for Container.ReactiveNested. + /// + public partial class ReactiveNested + { + private static readonly PropertyChangedEventArgs _allPropsReactivePropChangedEventArgs = new PropertyChangedEventArgs(nameof(AllPropsReactiveProp)); + + public partial string AllPropsReactiveProp + { + get => field; + set + { + if (!Equals(field, value)) + { + field = value; + OnPropertyChanged(_allPropsReactivePropChangedEventArgs); + } + } + } + } +} + + }, + { + FileName: Container.ReactiveProperties.g.cs, + Source: +// +#nullable enable + +using System.ComponentModel; +using System.Runtime.CompilerServices; + +/// +/// A partial class implementation for Container. +/// +public partial class Container +{ + private static readonly PropertyChangedEventArgs _containerPropChangedEventArgs = new PropertyChangedEventArgs(nameof(ContainerProp)); + + public partial string ContainerProp + { + get => field; + set + { + if (!Equals(field, value)) + { + field = value; + OnPropertyChanged(_containerPropChangedEventArgs); + } + } + } +} + }, { FileName: IgnoreReactiveAttribute.g.cs, Source: using System; -[AttributeUsage(AttributeTargets.Property, Inherited = false, AllowMultiple = false)] +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = false, AllowMultiple = false)] sealed class IgnoreReactiveAttribute : Attribute { public IgnoreReactiveAttribute() { } @@ -131,7 +196,7 @@ sealed class IgnoreReactiveAttribute : Attribute Source: using System; -[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = false, AllowMultiple = false)] +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = true, AllowMultiple = false)] sealed class ReactiveAttribute : Attribute { public ReactiveAttribute() { } diff --git a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.NestedClassesWithReactiveObjectInheritance.verified.txt b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.NestedClassesWithReactiveObjectInheritance.verified.txt index 4776135..b0f23e7 100644 --- a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.NestedClassesWithReactiveObjectInheritance.verified.txt +++ b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.NestedClassesWithReactiveObjectInheritance.verified.txt @@ -29,7 +29,7 @@ public partial class Container Source: using System; -[AttributeUsage(AttributeTargets.Property, Inherited = false, AllowMultiple = false)] +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = false, AllowMultiple = false)] sealed class IgnoreReactiveAttribute : Attribute { public IgnoreReactiveAttribute() { } @@ -40,7 +40,7 @@ sealed class IgnoreReactiveAttribute : Attribute Source: using System; -[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = false, AllowMultiple = false)] +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = true, AllowMultiple = false)] sealed class ReactiveAttribute : Attribute { public ReactiveAttribute() { } diff --git a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.NestedClassesWithStaticAndInstanceMembers.verified.txt b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.NestedClassesWithStaticAndInstanceMembers.verified.txt index 4ce9ee1..a5401f1 100644 --- a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.NestedClassesWithStaticAndInstanceMembers.verified.txt +++ b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.NestedClassesWithStaticAndInstanceMembers.verified.txt @@ -1,11 +1,87 @@ { Sources: [ + { + FileName: Container.Nested.INPC.g.cs, + Source: +// +#nullable enable + +using System.ComponentModel; +using System.Runtime.CompilerServices; + +public partial class Container +{ + public partial class Nested : INotifyPropertyChanged + { + public event PropertyChangedEventHandler? PropertyChanged; + + protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null) + { + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); + } + + protected virtual void OnPropertyChanged(PropertyChangedEventArgs args) + { + PropertyChanged?.Invoke(this, args); + } + } +} + + }, + { + FileName: Container.Nested.ReactiveProperties.g.cs, + Source: +// +#nullable enable + +using System.ComponentModel; +using System.Runtime.CompilerServices; + +public partial class Container +{ + /// + /// A partial class implementation for Container.Nested. + /// + public partial class Nested + { + private static readonly PropertyChangedEventArgs _staticPropChangedEventArgs = new PropertyChangedEventArgs(nameof(StaticProp)); + private static readonly PropertyChangedEventArgs _instancePropChangedEventArgs = new PropertyChangedEventArgs(nameof(InstanceProp)); + + public partial string StaticProp + { + get => field; + set + { + if (!Equals(field, value)) + { + field = value; + OnPropertyChanged(_staticPropChangedEventArgs); + } + } + } + + public partial string InstanceProp + { + get => field; + set + { + if (!Equals(field, value)) + { + field = value; + OnPropertyChanged(_instancePropChangedEventArgs); + } + } + } + } +} + + }, { FileName: IgnoreReactiveAttribute.g.cs, Source: using System; -[AttributeUsage(AttributeTargets.Property, Inherited = false, AllowMultiple = false)] +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = false, AllowMultiple = false)] sealed class IgnoreReactiveAttribute : Attribute { public IgnoreReactiveAttribute() { } @@ -16,7 +92,7 @@ sealed class IgnoreReactiveAttribute : Attribute Source: using System; -[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = false, AllowMultiple = false)] +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = true, AllowMultiple = false)] sealed class ReactiveAttribute : Attribute { public ReactiveAttribute() { } diff --git a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.NestedPrivateClassWithReactiveProperties.verified.txt b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.NestedPrivateClassWithReactiveProperties.verified.txt index 4ce9ee1..1a5c0ca 100644 --- a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.NestedPrivateClassWithReactiveProperties.verified.txt +++ b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.NestedPrivateClassWithReactiveProperties.verified.txt @@ -5,18 +5,150 @@ Source: using System; -[AttributeUsage(AttributeTargets.Property, Inherited = false, AllowMultiple = false)] +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = false, AllowMultiple = false)] sealed class IgnoreReactiveAttribute : Attribute { public IgnoreReactiveAttribute() { } } + }, + { + FileName: OuterClass.PrivateInnerClass.INPC.g.cs, + Source: +// +#nullable enable + +using System.ComponentModel; +using System.Runtime.CompilerServices; + +public partial class OuterClass +{ + private partial class PrivateInnerClass : INotifyPropertyChanged + { + public event PropertyChangedEventHandler? PropertyChanged; + + protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null) + { + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); + } + + protected virtual void OnPropertyChanged(PropertyChangedEventArgs args) + { + PropertyChanged?.Invoke(this, args); + } + } +} + + }, + { + FileName: OuterClass.PrivateInnerClass.ReactiveProperties.g.cs, + Source: +// +#nullable enable + +using System.ComponentModel; +using System.Runtime.CompilerServices; + +public partial class OuterClass +{ + private partial class PrivateInnerClass + { + private static readonly PropertyChangedEventArgs _innerPropChangedEventArgs = new PropertyChangedEventArgs(nameof(InnerProp)); + private static readonly PropertyChangedEventArgs _privateInnerPropChangedEventArgs = new PropertyChangedEventArgs(nameof(PrivateInnerProp)); + + public partial string InnerProp + { + get => field; + set + { + if (!Equals(field, value)) + { + field = value; + OnPropertyChanged(_innerPropChangedEventArgs); + } + } + } + + private partial int PrivateInnerProp + { + get => field; + set + { + if (!Equals(field, value)) + { + field = value; + OnPropertyChanged(_privateInnerPropChangedEventArgs); + } + } + } + } +} + + }, + { + FileName: OuterClass.ProtectedInnerClass.INPC.g.cs, + Source: +// +#nullable enable + +using System.ComponentModel; +using System.Runtime.CompilerServices; + +public partial class OuterClass +{ + protected partial class ProtectedInnerClass : INotifyPropertyChanged + { + public event PropertyChangedEventHandler? PropertyChanged; + + protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null) + { + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); + } + + protected virtual void OnPropertyChanged(PropertyChangedEventArgs args) + { + PropertyChanged?.Invoke(this, args); + } + } +} + + }, + { + FileName: OuterClass.ProtectedInnerClass.ReactiveProperties.g.cs, + Source: +// +#nullable enable + +using System.ComponentModel; +using System.Runtime.CompilerServices; + +public partial class OuterClass +{ + protected partial class ProtectedInnerClass + { + private static readonly PropertyChangedEventArgs _protectedClassPropChangedEventArgs = new PropertyChangedEventArgs(nameof(ProtectedClassProp)); + + public partial string ProtectedClassProp + { + get => field; + set + { + if (!Equals(field, value)) + { + field = value; + OnPropertyChanged(_protectedClassPropChangedEventArgs); + } + } + } + } +} + }, { FileName: ReactiveAttribute.g.cs, Source: using System; -[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = false, AllowMultiple = false)] +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = true, AllowMultiple = false)] sealed class ReactiveAttribute : Attribute { public ReactiveAttribute() { } diff --git a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.NonReactiveObjectWithMixedProperties.verified.txt b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.NonReactiveObjectWithMixedProperties.verified.txt index 69d6247..871ab16 100644 --- a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.NonReactiveObjectWithMixedProperties.verified.txt +++ b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.NonReactiveObjectWithMixedProperties.verified.txt @@ -5,7 +5,7 @@ Source: using System; -[AttributeUsage(AttributeTargets.Property, Inherited = false, AllowMultiple = false)] +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = false, AllowMultiple = false)] sealed class IgnoreReactiveAttribute : Attribute { public IgnoreReactiveAttribute() { } @@ -16,7 +16,7 @@ sealed class IgnoreReactiveAttribute : Attribute Source: using System; -[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = false, AllowMultiple = false)] +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = true, AllowMultiple = false)] sealed class ReactiveAttribute : Attribute { public ReactiveAttribute() { } diff --git a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.PropertyLevelReactiveWithCustomAccessors.verified.txt b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.PropertyLevelReactiveWithCustomAccessors.verified.txt index e9837d2..01de478 100644 --- a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.PropertyLevelReactiveWithCustomAccessors.verified.txt +++ b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.PropertyLevelReactiveWithCustomAccessors.verified.txt @@ -5,7 +5,7 @@ Source: using System; -[AttributeUsage(AttributeTargets.Property, Inherited = false, AllowMultiple = false)] +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = false, AllowMultiple = false)] sealed class IgnoreReactiveAttribute : Attribute { public IgnoreReactiveAttribute() { } @@ -16,7 +16,7 @@ sealed class IgnoreReactiveAttribute : Attribute Source: using System; -[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = false, AllowMultiple = false)] +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = true, AllowMultiple = false)] sealed class ReactiveAttribute : Attribute { public ReactiveAttribute() { } diff --git a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.PropertyLevelReactiveWithGenericType.verified.txt b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.PropertyLevelReactiveWithGenericType.verified.txt index b888c13..3a5fc1b 100644 --- a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.PropertyLevelReactiveWithGenericType.verified.txt +++ b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.PropertyLevelReactiveWithGenericType.verified.txt @@ -5,7 +5,7 @@ Source: using System; -[AttributeUsage(AttributeTargets.Property, Inherited = false, AllowMultiple = false)] +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = false, AllowMultiple = false)] sealed class IgnoreReactiveAttribute : Attribute { public IgnoreReactiveAttribute() { } @@ -16,7 +16,7 @@ sealed class IgnoreReactiveAttribute : Attribute Source: using System; -[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = false, AllowMultiple = false)] +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = true, AllowMultiple = false)] sealed class ReactiveAttribute : Attribute { public ReactiveAttribute() { } diff --git a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.PropertyLevelReactiveWithInheritance.verified.txt b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.PropertyLevelReactiveWithInheritance.verified.txt index e13b5e2..6a820f2 100644 --- a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.PropertyLevelReactiveWithInheritance.verified.txt +++ b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.PropertyLevelReactiveWithInheritance.verified.txt @@ -92,7 +92,7 @@ public partial class DerivedClass Source: using System; -[AttributeUsage(AttributeTargets.Property, Inherited = false, AllowMultiple = false)] +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = false, AllowMultiple = false)] sealed class IgnoreReactiveAttribute : Attribute { public IgnoreReactiveAttribute() { } @@ -103,7 +103,7 @@ sealed class IgnoreReactiveAttribute : Attribute Source: using System; -[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = false, AllowMultiple = false)] +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = true, AllowMultiple = false)] sealed class ReactiveAttribute : Attribute { public ReactiveAttribute() { } diff --git a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.PropertyLevelReactiveWithMixedProperties.verified.txt b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.PropertyLevelReactiveWithMixedProperties.verified.txt index 6a80b78..9bb4803 100644 --- a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.PropertyLevelReactiveWithMixedProperties.verified.txt +++ b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.PropertyLevelReactiveWithMixedProperties.verified.txt @@ -5,7 +5,7 @@ Source: using System; -[AttributeUsage(AttributeTargets.Property, Inherited = false, AllowMultiple = false)] +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = false, AllowMultiple = false)] sealed class IgnoreReactiveAttribute : Attribute { public IgnoreReactiveAttribute() { } @@ -16,7 +16,7 @@ sealed class IgnoreReactiveAttribute : Attribute Source: using System; -[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = false, AllowMultiple = false)] +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = true, AllowMultiple = false)] sealed class ReactiveAttribute : Attribute { public ReactiveAttribute() { } diff --git a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ReactiveObjectDerivedWithComplexProperties.verified.txt b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ReactiveObjectDerivedWithComplexProperties.verified.txt index 8f2e1aa..87f933f 100644 --- a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ReactiveObjectDerivedWithComplexProperties.verified.txt +++ b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ReactiveObjectDerivedWithComplexProperties.verified.txt @@ -5,7 +5,7 @@ Source: using System; -[AttributeUsage(AttributeTargets.Property, Inherited = false, AllowMultiple = false)] +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = false, AllowMultiple = false)] sealed class IgnoreReactiveAttribute : Attribute { public IgnoreReactiveAttribute() { } @@ -16,7 +16,7 @@ sealed class IgnoreReactiveAttribute : Attribute Source: using System; -[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = false, AllowMultiple = false)] +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = true, AllowMultiple = false)] sealed class ReactiveAttribute : Attribute { public ReactiveAttribute() { } diff --git a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ReactiveObjectDerivedWithCustomImplementations.verified.txt b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ReactiveObjectDerivedWithCustomImplementations.verified.txt index edbd5b4..691deb2 100644 --- a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ReactiveObjectDerivedWithCustomImplementations.verified.txt +++ b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ReactiveObjectDerivedWithCustomImplementations.verified.txt @@ -5,7 +5,7 @@ Source: using System; -[AttributeUsage(AttributeTargets.Property, Inherited = false, AllowMultiple = false)] +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = false, AllowMultiple = false)] sealed class IgnoreReactiveAttribute : Attribute { public IgnoreReactiveAttribute() { } @@ -16,7 +16,7 @@ sealed class IgnoreReactiveAttribute : Attribute Source: using System; -[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = false, AllowMultiple = false)] +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = true, AllowMultiple = false)] sealed class ReactiveAttribute : Attribute { public ReactiveAttribute() { } diff --git a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ReactiveObjectDerivedWithInheritance.verified.txt b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ReactiveObjectDerivedWithInheritance.verified.txt index 1db86fb..062152d 100644 --- a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ReactiveObjectDerivedWithInheritance.verified.txt +++ b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ReactiveObjectDerivedWithInheritance.verified.txt @@ -68,7 +68,7 @@ public partial class GrandChildViewModel Source: using System; -[AttributeUsage(AttributeTargets.Property, Inherited = false, AllowMultiple = false)] +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = false, AllowMultiple = false)] sealed class IgnoreReactiveAttribute : Attribute { public IgnoreReactiveAttribute() { } @@ -79,7 +79,7 @@ sealed class IgnoreReactiveAttribute : Attribute Source: using System; -[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = false, AllowMultiple = false)] +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = true, AllowMultiple = false)] sealed class ReactiveAttribute : Attribute { public ReactiveAttribute() { } diff --git a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ReactiveObjectDerivedWithInitProperties.verified.txt b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ReactiveObjectDerivedWithInitProperties.verified.txt index b9417a5..50b5305 100644 --- a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ReactiveObjectDerivedWithInitProperties.verified.txt +++ b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ReactiveObjectDerivedWithInitProperties.verified.txt @@ -5,7 +5,7 @@ Source: using System; -[AttributeUsage(AttributeTargets.Property, Inherited = false, AllowMultiple = false)] +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = false, AllowMultiple = false)] sealed class IgnoreReactiveAttribute : Attribute { public IgnoreReactiveAttribute() { } @@ -16,7 +16,7 @@ sealed class IgnoreReactiveAttribute : Attribute Source: using System; -[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = false, AllowMultiple = false)] +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = true, AllowMultiple = false)] sealed class ReactiveAttribute : Attribute { public ReactiveAttribute() { } diff --git a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ReactiveObjectDerivedWithObservableProperties.verified.txt b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ReactiveObjectDerivedWithObservableProperties.verified.txt index e58f067..4dd20ae 100644 --- a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ReactiveObjectDerivedWithObservableProperties.verified.txt +++ b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ReactiveObjectDerivedWithObservableProperties.verified.txt @@ -5,7 +5,7 @@ Source: using System; -[AttributeUsage(AttributeTargets.Property, Inherited = false, AllowMultiple = false)] +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = false, AllowMultiple = false)] sealed class IgnoreReactiveAttribute : Attribute { public IgnoreReactiveAttribute() { } @@ -16,7 +16,7 @@ sealed class IgnoreReactiveAttribute : Attribute Source: using System; -[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = false, AllowMultiple = false)] +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = true, AllowMultiple = false)] sealed class ReactiveAttribute : Attribute { public ReactiveAttribute() { } diff --git a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ReactiveObjectWithClassLevelReactive.verified.txt b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ReactiveObjectWithClassLevelReactive.verified.txt index 901e896..61115e2 100644 --- a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ReactiveObjectWithClassLevelReactive.verified.txt +++ b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ReactiveObjectWithClassLevelReactive.verified.txt @@ -5,7 +5,7 @@ Source: using System; -[AttributeUsage(AttributeTargets.Property, Inherited = false, AllowMultiple = false)] +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = false, AllowMultiple = false)] sealed class IgnoreReactiveAttribute : Attribute { public IgnoreReactiveAttribute() { } @@ -16,7 +16,7 @@ sealed class IgnoreReactiveAttribute : Attribute Source: using System; -[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = false, AllowMultiple = false)] +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = true, AllowMultiple = false)] sealed class ReactiveAttribute : Attribute { public ReactiveAttribute() { } diff --git a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ReactiveObjectWithClassLevelReactiveAndIgnoreOverride.verified.txt b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ReactiveObjectWithClassLevelReactiveAndIgnoreOverride.verified.txt index d5117c7..18e6116 100644 --- a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ReactiveObjectWithClassLevelReactiveAndIgnoreOverride.verified.txt +++ b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ReactiveObjectWithClassLevelReactiveAndIgnoreOverride.verified.txt @@ -32,7 +32,7 @@ public partial class AllReactiveViewModel Source: using System; -[AttributeUsage(AttributeTargets.Property, Inherited = false, AllowMultiple = false)] +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = false, AllowMultiple = false)] sealed class IgnoreReactiveAttribute : Attribute { public IgnoreReactiveAttribute() { } @@ -43,7 +43,7 @@ sealed class IgnoreReactiveAttribute : Attribute Source: using System; -[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = false, AllowMultiple = false)] +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = true, AllowMultiple = false)] sealed class ReactiveAttribute : Attribute { public ReactiveAttribute() { } diff --git a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ReactiveObjectWithMixedReactiveProperties.verified.txt b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ReactiveObjectWithMixedReactiveProperties.verified.txt index e009866..13bf5c9 100644 --- a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ReactiveObjectWithMixedReactiveProperties.verified.txt +++ b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ReactiveObjectWithMixedReactiveProperties.verified.txt @@ -5,7 +5,7 @@ Source: using System; -[AttributeUsage(AttributeTargets.Property, Inherited = false, AllowMultiple = false)] +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = false, AllowMultiple = false)] sealed class IgnoreReactiveAttribute : Attribute { public IgnoreReactiveAttribute() { } @@ -43,7 +43,7 @@ public partial class MixedViewModel Source: using System; -[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = false, AllowMultiple = false)] +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = true, AllowMultiple = false)] sealed class ReactiveAttribute : Attribute { public ReactiveAttribute() { } diff --git a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ReactiveObjectWithNullableGenerics.verified.txt b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ReactiveObjectWithNullableGenerics.verified.txt index 6988d4e..249940e 100644 --- a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ReactiveObjectWithNullableGenerics.verified.txt +++ b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ReactiveObjectWithNullableGenerics.verified.txt @@ -5,7 +5,7 @@ Source: using System; -[AttributeUsage(AttributeTargets.Property, Inherited = false, AllowMultiple = false)] +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = false, AllowMultiple = false)] sealed class IgnoreReactiveAttribute : Attribute { public IgnoreReactiveAttribute() { } @@ -86,7 +86,7 @@ public partial class NullableGenericsTest Source: using System; -[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = false, AllowMultiple = false)] +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = true, AllowMultiple = false)] sealed class ReactiveAttribute : Attribute { public ReactiveAttribute() { } diff --git a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ReactiveObjectWithPropertyInitializer.verified.txt b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ReactiveObjectWithPropertyInitializer.verified.txt index 134cb90..5a84ca4 100644 --- a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ReactiveObjectWithPropertyInitializer.verified.txt +++ b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ReactiveObjectWithPropertyInitializer.verified.txt @@ -5,7 +5,7 @@ Source: using System; -[AttributeUsage(AttributeTargets.Property, Inherited = false, AllowMultiple = false)] +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = false, AllowMultiple = false)] sealed class IgnoreReactiveAttribute : Attribute { public IgnoreReactiveAttribute() { } @@ -43,7 +43,7 @@ public partial class InitializedViewModel Source: using System; -[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = false, AllowMultiple = false)] +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = true, AllowMultiple = false)] sealed class ReactiveAttribute : Attribute { public ReactiveAttribute() { } diff --git a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ReactiveObjectWithSingleReactiveProperty.verified.txt b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ReactiveObjectWithSingleReactiveProperty.verified.txt index 945037b..ab514a8 100644 --- a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ReactiveObjectWithSingleReactiveProperty.verified.txt +++ b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ReactiveObjectWithSingleReactiveProperty.verified.txt @@ -26,7 +26,7 @@ public partial class Car Source: using System; -[AttributeUsage(AttributeTargets.Property, Inherited = false, AllowMultiple = false)] +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = false, AllowMultiple = false)] sealed class IgnoreReactiveAttribute : Attribute { public IgnoreReactiveAttribute() { } @@ -37,7 +37,7 @@ sealed class IgnoreReactiveAttribute : Attribute Source: using System; -[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = false, AllowMultiple = false)] +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = true, AllowMultiple = false)] sealed class ReactiveAttribute : Attribute { public ReactiveAttribute() { } diff --git a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ReactiveObjectWithoutAnyReactiveAttribute.verified.txt b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ReactiveObjectWithoutAnyReactiveAttribute.verified.txt index 4ce9ee1..ab7c920 100644 --- a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ReactiveObjectWithoutAnyReactiveAttribute.verified.txt +++ b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.ReactiveObjectWithoutAnyReactiveAttribute.verified.txt @@ -5,7 +5,7 @@ Source: using System; -[AttributeUsage(AttributeTargets.Property, Inherited = false, AllowMultiple = false)] +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = false, AllowMultiple = false)] sealed class IgnoreReactiveAttribute : Attribute { public IgnoreReactiveAttribute() { } @@ -16,7 +16,7 @@ sealed class IgnoreReactiveAttribute : Attribute Source: using System; -[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = false, AllowMultiple = false)] +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = true, AllowMultiple = false)] sealed class ReactiveAttribute : Attribute { public ReactiveAttribute() { } diff --git a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.SimpleClassWithReactiveAttribute.verified.txt b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.SimpleClassWithReactiveAttribute.verified.txt index 4ce9ee1..1753453 100644 --- a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.SimpleClassWithReactiveAttribute.verified.txt +++ b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.SimpleClassWithReactiveAttribute.verified.txt @@ -5,7 +5,7 @@ Source: using System; -[AttributeUsage(AttributeTargets.Property, Inherited = false, AllowMultiple = false)] +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = false, AllowMultiple = false)] sealed class IgnoreReactiveAttribute : Attribute { public IgnoreReactiveAttribute() { } @@ -16,11 +16,67 @@ sealed class IgnoreReactiveAttribute : Attribute Source: using System; -[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = false, AllowMultiple = false)] +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = true, AllowMultiple = false)] sealed class ReactiveAttribute : Attribute { public ReactiveAttribute() { } } + }, + { + FileName: TestClass.INPC.g.cs, + Source: +// +#nullable enable + +using System.ComponentModel; +using System.Runtime.CompilerServices; + +public partial class TestClass : INotifyPropertyChanged +{ + public event PropertyChangedEventHandler? PropertyChanged; + + protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null) + { + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); + } + + protected virtual void OnPropertyChanged(PropertyChangedEventArgs args) + { + PropertyChanged?.Invoke(this, args); + } +} + + }, + { + FileName: TestClass.ReactiveProperties.g.cs, + Source: +// +#nullable enable + +using System.ComponentModel; +using System.Runtime.CompilerServices; + +/// +/// A partial class implementation for TestClass. +/// +public partial class TestClass +{ + private static readonly PropertyChangedEventArgs _nameChangedEventArgs = new PropertyChangedEventArgs(nameof(Name)); + + public partial string Name + { + get => field; + set + { + if (!Equals(field, value)) + { + field = value; + OnPropertyChanged(_nameChangedEventArgs); + } + } + } +} + } ], Diagnostics: null diff --git a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.UseLegacyModeTest.verified.txt b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.UseLegacyModeTest.verified.txt index 4ce9ee1..c0ef879 100644 --- a/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.UseLegacyModeTest.verified.txt +++ b/ReactiveGenerator.Tests/Snapshots/ReactiveGeneratorTests.UseLegacyModeTest.verified.txt @@ -5,7 +5,7 @@ Source: using System; -[AttributeUsage(AttributeTargets.Property, Inherited = false, AllowMultiple = false)] +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = false, AllowMultiple = false)] sealed class IgnoreReactiveAttribute : Attribute { public IgnoreReactiveAttribute() { } @@ -16,11 +16,69 @@ sealed class IgnoreReactiveAttribute : Attribute Source: using System; -[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = false, AllowMultiple = false)] +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = true, AllowMultiple = false)] sealed class ReactiveAttribute : Attribute { public ReactiveAttribute() { } } + }, + { + FileName: TestClass.INPC.g.cs, + Source: +// +#nullable enable + +using System.ComponentModel; +using System.Runtime.CompilerServices; + +public partial class TestClass : INotifyPropertyChanged +{ + public event PropertyChangedEventHandler? PropertyChanged; + + protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null) + { + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); + } + + protected virtual void OnPropertyChanged(PropertyChangedEventArgs args) + { + PropertyChanged?.Invoke(this, args); + } +} + + }, + { + FileName: TestClass.ReactiveProperties.g.cs, + Source: +// +#nullable enable + +using System.ComponentModel; +using System.Runtime.CompilerServices; + +/// +/// A partial class implementation for TestClass. +/// +public partial class TestClass +{ + private string _name; + + private static readonly PropertyChangedEventArgs _nameChangedEventArgs = new PropertyChangedEventArgs(nameof(Name)); + + public partial string Name + { + get => _name; + set + { + if (!Equals(_name, value)) + { + _name = value; + OnPropertyChanged(_nameChangedEventArgs); + } + } + } +} + } ], Diagnostics: null From 701ef03051cc749df3e9cbe0eeadb49a89e01059 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wies=C5=82aw=20S=CC=8Colte=CC=81s?= Date: Wed, 25 Dec 2024 20:33:49 +0100 Subject: [PATCH 10/10] Add tests --- ReactiveGenerator.Tests/CrossAssemblyTests.cs | 315 ++++++++++++++++++ ...es_DerivedHasPropertyReactive.verified.txt | 89 +++++ ...Attributes_DerivedHasReactive.verified.txt | 89 +++++ ...artialReactive_DerivedExtends.verified.txt | 75 +++++ ...active_DerivedHasNoAttributes.verified.txt | 27 ++ ...tive_DerivedHasIgnoreReactive.verified.txt | 27 ++ ...vedHasMixedPropertyAttributes.verified.txt | 75 +++++ ...active_DerivedHasNoAttributes.verified.txt | 61 ++++ ...evels_MixedReactiveAttributes.verified.txt | 109 ++++++ 9 files changed, 867 insertions(+) create mode 100644 ReactiveGenerator.Tests/Snapshots/CrossAssemblyTests.BaseHasNoAttributes_DerivedHasPropertyReactive.verified.txt create mode 100644 ReactiveGenerator.Tests/Snapshots/CrossAssemblyTests.BaseHasNoAttributes_DerivedHasReactive.verified.txt create mode 100644 ReactiveGenerator.Tests/Snapshots/CrossAssemblyTests.BaseHasPartialReactive_DerivedExtends.verified.txt create mode 100644 ReactiveGenerator.Tests/Snapshots/CrossAssemblyTests.BaseHasPropertyReactive_DerivedHasNoAttributes.verified.txt create mode 100644 ReactiveGenerator.Tests/Snapshots/CrossAssemblyTests.BaseHasReactive_DerivedHasIgnoreReactive.verified.txt create mode 100644 ReactiveGenerator.Tests/Snapshots/CrossAssemblyTests.BaseHasReactive_DerivedHasMixedPropertyAttributes.verified.txt create mode 100644 ReactiveGenerator.Tests/Snapshots/CrossAssemblyTests.BaseHasReactive_DerivedHasNoAttributes.verified.txt create mode 100644 ReactiveGenerator.Tests/Snapshots/CrossAssemblyTests.MultipleInheritanceLevels_MixedReactiveAttributes.verified.txt diff --git a/ReactiveGenerator.Tests/CrossAssemblyTests.cs b/ReactiveGenerator.Tests/CrossAssemblyTests.cs index 5fb50e8..2fabb04 100644 --- a/ReactiveGenerator.Tests/CrossAssemblyTests.cs +++ b/ReactiveGenerator.Tests/CrossAssemblyTests.cs @@ -172,5 +172,320 @@ public partial class ChildViewModel : ExternalViewModel new ReactiveGenerator() ); } + + /// + /// External base has [Reactive], derived has no attributes + /// + [Fact] + public Task BaseHasReactive_DerivedHasNoAttributes() + { + var externalAssemblySource = @" +namespace ExternalLib +{ + [Reactive] + public partial class BaseClass + { + public partial string BaseProp { get; set; } + } +}"; + + var mainAssemblySource = @" +using ExternalLib; + +namespace MainLib +{ + // No [Reactive] here, should inherit from base + public partial class DerivedClass : BaseClass + { + public partial string DerivedProp { get; set; } + } +}"; + + return SourceGeneratorTestHelper.TestCrossAssemblyAndVerifyWithExternalGen( + externalAssemblySource, + mainAssemblySource, + null, + new ReactiveGenerator()); + } + + /// + /// External base has no attributes, derived has [Reactive] + /// + [Fact] + public Task BaseHasNoAttributes_DerivedHasReactive() + { + var externalAssemblySource = @" +namespace ExternalLib +{ + public partial class BaseClass + { + public partial string BaseProp { get; set; } + } +}"; + + var mainAssemblySource = @" +using ExternalLib; + +namespace MainLib +{ + [Reactive] + public partial class DerivedClass : BaseClass + { + public partial string DerivedProp { get; set; } + } +}"; + + return SourceGeneratorTestHelper.TestCrossAssemblyAndVerifyWithExternalGen( + externalAssemblySource, + mainAssemblySource, + null, + new ReactiveGenerator()); + } + + /// + /// External base has property-level [Reactive], derived has no attributes + /// + [Fact] + public Task BaseHasPropertyReactive_DerivedHasNoAttributes() + { + var externalAssemblySource = @" +namespace ExternalLib +{ + public partial class BaseClass + { + [Reactive] + public partial string ReactiveProp { get; set; } + public partial string NonReactiveProp { get; set; } + } +}"; + + var mainAssemblySource = @" +using ExternalLib; + +namespace MainLib +{ + public partial class DerivedClass : BaseClass + { + public partial string DerivedProp { get; set; } + } +}"; + + return SourceGeneratorTestHelper.TestCrossAssemblyAndVerifyWithExternalGen( + externalAssemblySource, + mainAssemblySource, + null, + new ReactiveGenerator()); + } + + /// + /// External base has no attributes, derived has property-level [Reactive] + /// + [Fact] + public Task BaseHasNoAttributes_DerivedHasPropertyReactive() + { + var externalAssemblySource = @" +namespace ExternalLib +{ + public partial class BaseClass + { + public partial string BaseProp { get; set; } + } +}"; + + var mainAssemblySource = @" +using ExternalLib; + +namespace MainLib +{ + public partial class DerivedClass : BaseClass + { + [Reactive] + public partial string ReactiveProp { get; set; } + public partial string NonReactiveProp { get; set; } + } +}"; + + return SourceGeneratorTestHelper.TestCrossAssemblyAndVerifyWithExternalGen( + externalAssemblySource, + mainAssemblySource, + null, + new ReactiveGenerator()); + } + + /// + /// External base has [Reactive], derived has [IgnoreReactive] + /// + [Fact] + public Task BaseHasReactive_DerivedHasIgnoreReactive() + { + var externalAssemblySource = @" +namespace ExternalLib +{ + [Reactive] + public partial class BaseClass + { + public partial string BaseProp { get; set; } + } +}"; + + var mainAssemblySource = @" +using ExternalLib; + +namespace MainLib +{ + [IgnoreReactive] + public partial class DerivedClass : BaseClass + { + public partial string DerivedProp { get; set; } + } +}"; + + return SourceGeneratorTestHelper.TestCrossAssemblyAndVerifyWithExternalGen( + externalAssemblySource, + mainAssemblySource, + null, + new ReactiveGenerator()); + } + + /// + /// External base has [Reactive], derived has mixed property-level attributes + /// + [Fact] + public Task BaseHasReactive_DerivedHasMixedPropertyAttributes() + { + var externalAssemblySource = @" +namespace ExternalLib +{ + [Reactive] + public partial class BaseClass + { + public partial string BaseProp { get; set; } + [IgnoreReactive] + public partial string IgnoredBaseProp { get; set; } + } +}"; + + var mainAssemblySource = @" +using ExternalLib; + +namespace MainLib +{ + public partial class DerivedClass : BaseClass + { + // Should be reactive due to base class + public partial string InheritedReactiveProp { get; set; } + + // Should be ignored + [IgnoreReactive] + public partial string IgnoredProp { get; set; } + + // Should be reactive due to explicit attribute + [Reactive] + public partial string ExplicitReactiveProp { get; set; } + } +}"; + + return SourceGeneratorTestHelper.TestCrossAssemblyAndVerifyWithExternalGen( + externalAssemblySource, + mainAssemblySource, + null, + new ReactiveGenerator()); + } + + /// + /// Multiple inheritance levels with mixed reactive attributes + /// + [Fact] + public Task MultipleInheritanceLevels_MixedReactiveAttributes() + { + var externalAssemblySource = @" +namespace ExternalLib +{ + [Reactive] + public partial class GrandparentClass + { + public partial string GrandparentProp { get; set; } + } + + // No attributes here + public partial class ParentClass : GrandparentClass + { + public partial string ParentProp { get; set; } + [Reactive] + public partial string ReactiveParentProp { get; set; } + } +}"; + + var mainAssemblySource = @" +using ExternalLib; + +namespace MainLib +{ + // No class-level reactive + public partial class ChildClass : ParentClass + { + public partial string ChildProp { get; set; } + [Reactive] + public partial string ReactiveChildProp { get; set; } + } + + [IgnoreReactive] + public partial class GrandchildClass : ChildClass + { + public partial string GrandchildProp { get; set; } + [Reactive] + public partial string ReactiveGrandchildProp { get; set; } + } +}"; + + return SourceGeneratorTestHelper.TestCrossAssemblyAndVerifyWithExternalGen( + externalAssemblySource, + mainAssemblySource, + null, + new ReactiveGenerator()); + } + + /// + /// External base has partial [Reactive] implementation, derived extends it + /// + [Fact] + public Task BaseHasPartialReactive_DerivedExtends() + { + var externalAssemblySource = @" +namespace ExternalLib +{ + [Reactive] + public abstract partial class BaseClass + { + public partial string BaseProp { get; set; } + public abstract string AbstractProp { get; set; } + public virtual partial string VirtualProp { get; set; } + } +}"; + + var mainAssemblySource = @" +using ExternalLib; + +namespace MainLib +{ + public partial class DerivedClass : BaseClass + { + // Implementing abstract prop + public override string AbstractProp { get; set; } + + // Overriding virtual prop + public override partial string VirtualProp { get; set; } + + // New prop + public partial string DerivedProp { get; set; } + } +}"; + + return SourceGeneratorTestHelper.TestCrossAssemblyAndVerifyWithExternalGen( + externalAssemblySource, + mainAssemblySource, + null, + new ReactiveGenerator()); + } } } diff --git a/ReactiveGenerator.Tests/Snapshots/CrossAssemblyTests.BaseHasNoAttributes_DerivedHasPropertyReactive.verified.txt b/ReactiveGenerator.Tests/Snapshots/CrossAssemblyTests.BaseHasNoAttributes_DerivedHasPropertyReactive.verified.txt new file mode 100644 index 0000000..f2ed698 --- /dev/null +++ b/ReactiveGenerator.Tests/Snapshots/CrossAssemblyTests.BaseHasNoAttributes_DerivedHasPropertyReactive.verified.txt @@ -0,0 +1,89 @@ +{ + Sources: [ + { + FileName: IgnoreReactiveAttribute.g.cs, + Source: +using System; + +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = false, AllowMultiple = false)] +sealed class IgnoreReactiveAttribute : Attribute +{ + public IgnoreReactiveAttribute() { } +} + }, + { + FileName: MainLib.DerivedClass.INPC.g.cs, + Source: +// +#nullable enable + +using System.ComponentModel; +using System.Runtime.CompilerServices; + +namespace MainLib +{ + public partial class DerivedClass : INotifyPropertyChanged + { + public event PropertyChangedEventHandler? PropertyChanged; + + protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null) + { + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); + } + + protected virtual void OnPropertyChanged(PropertyChangedEventArgs args) + { + PropertyChanged?.Invoke(this, args); + } + } +} + + }, + { + FileName: MainLib.DerivedClass.ReactiveProperties.g.cs, + Source: +// +#nullable enable + +using System.ComponentModel; +using System.Runtime.CompilerServices; + +namespace MainLib +{ + /// + /// A partial class implementation for MainLib.DerivedClass. + /// + public partial class DerivedClass + { + private static readonly PropertyChangedEventArgs _reactivePropChangedEventArgs = new PropertyChangedEventArgs(nameof(ReactiveProp)); + + public partial string ReactiveProp + { + get => field; + set + { + if (!Equals(field, value)) + { + field = value; + OnPropertyChanged(_reactivePropChangedEventArgs); + } + } + } + } +} + + }, + { + FileName: ReactiveAttribute.g.cs, + Source: +using System; + +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = true, AllowMultiple = false)] +sealed class ReactiveAttribute : Attribute +{ + public ReactiveAttribute() { } +} + } + ], + Diagnostics: null +} \ No newline at end of file diff --git a/ReactiveGenerator.Tests/Snapshots/CrossAssemblyTests.BaseHasNoAttributes_DerivedHasReactive.verified.txt b/ReactiveGenerator.Tests/Snapshots/CrossAssemblyTests.BaseHasNoAttributes_DerivedHasReactive.verified.txt new file mode 100644 index 0000000..c0da5cd --- /dev/null +++ b/ReactiveGenerator.Tests/Snapshots/CrossAssemblyTests.BaseHasNoAttributes_DerivedHasReactive.verified.txt @@ -0,0 +1,89 @@ +{ + Sources: [ + { + FileName: IgnoreReactiveAttribute.g.cs, + Source: +using System; + +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = false, AllowMultiple = false)] +sealed class IgnoreReactiveAttribute : Attribute +{ + public IgnoreReactiveAttribute() { } +} + }, + { + FileName: MainLib.DerivedClass.INPC.g.cs, + Source: +// +#nullable enable + +using System.ComponentModel; +using System.Runtime.CompilerServices; + +namespace MainLib +{ + public partial class DerivedClass : INotifyPropertyChanged + { + public event PropertyChangedEventHandler? PropertyChanged; + + protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null) + { + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); + } + + protected virtual void OnPropertyChanged(PropertyChangedEventArgs args) + { + PropertyChanged?.Invoke(this, args); + } + } +} + + }, + { + FileName: MainLib.DerivedClass.ReactiveProperties.g.cs, + Source: +// +#nullable enable + +using System.ComponentModel; +using System.Runtime.CompilerServices; + +namespace MainLib +{ + /// + /// A partial class implementation for MainLib.DerivedClass. + /// + public partial class DerivedClass + { + private static readonly PropertyChangedEventArgs _derivedPropChangedEventArgs = new PropertyChangedEventArgs(nameof(DerivedProp)); + + public partial string DerivedProp + { + get => field; + set + { + if (!Equals(field, value)) + { + field = value; + OnPropertyChanged(_derivedPropChangedEventArgs); + } + } + } + } +} + + }, + { + FileName: ReactiveAttribute.g.cs, + Source: +using System; + +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = true, AllowMultiple = false)] +sealed class ReactiveAttribute : Attribute +{ + public ReactiveAttribute() { } +} + } + ], + Diagnostics: null +} \ No newline at end of file diff --git a/ReactiveGenerator.Tests/Snapshots/CrossAssemblyTests.BaseHasPartialReactive_DerivedExtends.verified.txt b/ReactiveGenerator.Tests/Snapshots/CrossAssemblyTests.BaseHasPartialReactive_DerivedExtends.verified.txt new file mode 100644 index 0000000..48eae67 --- /dev/null +++ b/ReactiveGenerator.Tests/Snapshots/CrossAssemblyTests.BaseHasPartialReactive_DerivedExtends.verified.txt @@ -0,0 +1,75 @@ +{ + Sources: [ + { + FileName: IgnoreReactiveAttribute.g.cs, + Source: +using System; + +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = false, AllowMultiple = false)] +sealed class IgnoreReactiveAttribute : Attribute +{ + public IgnoreReactiveAttribute() { } +} + }, + { + FileName: MainLib.DerivedClass.ReactiveProperties.g.cs, + Source: +// +#nullable enable + +using System.ComponentModel; +using System.Runtime.CompilerServices; + +namespace MainLib +{ + /// + /// A partial class implementation for MainLib.DerivedClass. + /// + public partial class DerivedClass + { + private static readonly PropertyChangedEventArgs _virtualPropChangedEventArgs = new PropertyChangedEventArgs(nameof(VirtualProp)); + private static readonly PropertyChangedEventArgs _derivedPropChangedEventArgs = new PropertyChangedEventArgs(nameof(DerivedProp)); + + public partial string VirtualProp + { + get => field; + set + { + if (!Equals(field, value)) + { + field = value; + OnPropertyChanged(_virtualPropChangedEventArgs); + } + } + } + + public partial string DerivedProp + { + get => field; + set + { + if (!Equals(field, value)) + { + field = value; + OnPropertyChanged(_derivedPropChangedEventArgs); + } + } + } + } +} + + }, + { + FileName: ReactiveAttribute.g.cs, + Source: +using System; + +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = true, AllowMultiple = false)] +sealed class ReactiveAttribute : Attribute +{ + public ReactiveAttribute() { } +} + } + ], + Diagnostics: null +} \ No newline at end of file diff --git a/ReactiveGenerator.Tests/Snapshots/CrossAssemblyTests.BaseHasPropertyReactive_DerivedHasNoAttributes.verified.txt b/ReactiveGenerator.Tests/Snapshots/CrossAssemblyTests.BaseHasPropertyReactive_DerivedHasNoAttributes.verified.txt new file mode 100644 index 0000000..ab7c920 --- /dev/null +++ b/ReactiveGenerator.Tests/Snapshots/CrossAssemblyTests.BaseHasPropertyReactive_DerivedHasNoAttributes.verified.txt @@ -0,0 +1,27 @@ +{ + Sources: [ + { + FileName: IgnoreReactiveAttribute.g.cs, + Source: +using System; + +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = false, AllowMultiple = false)] +sealed class IgnoreReactiveAttribute : Attribute +{ + public IgnoreReactiveAttribute() { } +} + }, + { + FileName: ReactiveAttribute.g.cs, + Source: +using System; + +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = true, AllowMultiple = false)] +sealed class ReactiveAttribute : Attribute +{ + public ReactiveAttribute() { } +} + } + ], + Diagnostics: null +} \ No newline at end of file diff --git a/ReactiveGenerator.Tests/Snapshots/CrossAssemblyTests.BaseHasReactive_DerivedHasIgnoreReactive.verified.txt b/ReactiveGenerator.Tests/Snapshots/CrossAssemblyTests.BaseHasReactive_DerivedHasIgnoreReactive.verified.txt new file mode 100644 index 0000000..ab7c920 --- /dev/null +++ b/ReactiveGenerator.Tests/Snapshots/CrossAssemblyTests.BaseHasReactive_DerivedHasIgnoreReactive.verified.txt @@ -0,0 +1,27 @@ +{ + Sources: [ + { + FileName: IgnoreReactiveAttribute.g.cs, + Source: +using System; + +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = false, AllowMultiple = false)] +sealed class IgnoreReactiveAttribute : Attribute +{ + public IgnoreReactiveAttribute() { } +} + }, + { + FileName: ReactiveAttribute.g.cs, + Source: +using System; + +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = true, AllowMultiple = false)] +sealed class ReactiveAttribute : Attribute +{ + public ReactiveAttribute() { } +} + } + ], + Diagnostics: null +} \ No newline at end of file diff --git a/ReactiveGenerator.Tests/Snapshots/CrossAssemblyTests.BaseHasReactive_DerivedHasMixedPropertyAttributes.verified.txt b/ReactiveGenerator.Tests/Snapshots/CrossAssemblyTests.BaseHasReactive_DerivedHasMixedPropertyAttributes.verified.txt new file mode 100644 index 0000000..067c1e7 --- /dev/null +++ b/ReactiveGenerator.Tests/Snapshots/CrossAssemblyTests.BaseHasReactive_DerivedHasMixedPropertyAttributes.verified.txt @@ -0,0 +1,75 @@ +{ + Sources: [ + { + FileName: IgnoreReactiveAttribute.g.cs, + Source: +using System; + +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = false, AllowMultiple = false)] +sealed class IgnoreReactiveAttribute : Attribute +{ + public IgnoreReactiveAttribute() { } +} + }, + { + FileName: MainLib.DerivedClass.ReactiveProperties.g.cs, + Source: +// +#nullable enable + +using System.ComponentModel; +using System.Runtime.CompilerServices; + +namespace MainLib +{ + /// + /// A partial class implementation for MainLib.DerivedClass. + /// + public partial class DerivedClass + { + private static readonly PropertyChangedEventArgs _inheritedReactivePropChangedEventArgs = new PropertyChangedEventArgs(nameof(InheritedReactiveProp)); + private static readonly PropertyChangedEventArgs _explicitReactivePropChangedEventArgs = new PropertyChangedEventArgs(nameof(ExplicitReactiveProp)); + + public partial string InheritedReactiveProp + { + get => field; + set + { + if (!Equals(field, value)) + { + field = value; + OnPropertyChanged(_inheritedReactivePropChangedEventArgs); + } + } + } + + public partial string ExplicitReactiveProp + { + get => field; + set + { + if (!Equals(field, value)) + { + field = value; + OnPropertyChanged(_explicitReactivePropChangedEventArgs); + } + } + } + } +} + + }, + { + FileName: ReactiveAttribute.g.cs, + Source: +using System; + +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = true, AllowMultiple = false)] +sealed class ReactiveAttribute : Attribute +{ + public ReactiveAttribute() { } +} + } + ], + Diagnostics: null +} \ No newline at end of file diff --git a/ReactiveGenerator.Tests/Snapshots/CrossAssemblyTests.BaseHasReactive_DerivedHasNoAttributes.verified.txt b/ReactiveGenerator.Tests/Snapshots/CrossAssemblyTests.BaseHasReactive_DerivedHasNoAttributes.verified.txt new file mode 100644 index 0000000..3e20f03 --- /dev/null +++ b/ReactiveGenerator.Tests/Snapshots/CrossAssemblyTests.BaseHasReactive_DerivedHasNoAttributes.verified.txt @@ -0,0 +1,61 @@ +{ + Sources: [ + { + FileName: IgnoreReactiveAttribute.g.cs, + Source: +using System; + +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = false, AllowMultiple = false)] +sealed class IgnoreReactiveAttribute : Attribute +{ + public IgnoreReactiveAttribute() { } +} + }, + { + FileName: MainLib.DerivedClass.ReactiveProperties.g.cs, + Source: +// +#nullable enable + +using System.ComponentModel; +using System.Runtime.CompilerServices; + +namespace MainLib +{ + /// + /// A partial class implementation for MainLib.DerivedClass. + /// + public partial class DerivedClass + { + private static readonly PropertyChangedEventArgs _derivedPropChangedEventArgs = new PropertyChangedEventArgs(nameof(DerivedProp)); + + public partial string DerivedProp + { + get => field; + set + { + if (!Equals(field, value)) + { + field = value; + OnPropertyChanged(_derivedPropChangedEventArgs); + } + } + } + } +} + + }, + { + FileName: ReactiveAttribute.g.cs, + Source: +using System; + +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = true, AllowMultiple = false)] +sealed class ReactiveAttribute : Attribute +{ + public ReactiveAttribute() { } +} + } + ], + Diagnostics: null +} \ No newline at end of file diff --git a/ReactiveGenerator.Tests/Snapshots/CrossAssemblyTests.MultipleInheritanceLevels_MixedReactiveAttributes.verified.txt b/ReactiveGenerator.Tests/Snapshots/CrossAssemblyTests.MultipleInheritanceLevels_MixedReactiveAttributes.verified.txt new file mode 100644 index 0000000..bc4adff --- /dev/null +++ b/ReactiveGenerator.Tests/Snapshots/CrossAssemblyTests.MultipleInheritanceLevels_MixedReactiveAttributes.verified.txt @@ -0,0 +1,109 @@ +{ + Sources: [ + { + FileName: IgnoreReactiveAttribute.g.cs, + Source: +using System; + +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = false, AllowMultiple = false)] +sealed class IgnoreReactiveAttribute : Attribute +{ + public IgnoreReactiveAttribute() { } +} + }, + { + FileName: MainLib.ChildClass.ReactiveProperties.g.cs, + Source: +// +#nullable enable + +using System.ComponentModel; +using System.Runtime.CompilerServices; + +namespace MainLib +{ + /// + /// A partial class implementation for MainLib.ChildClass. + /// + public partial class ChildClass + { + private static readonly PropertyChangedEventArgs _childPropChangedEventArgs = new PropertyChangedEventArgs(nameof(ChildProp)); + private static readonly PropertyChangedEventArgs _reactiveChildPropChangedEventArgs = new PropertyChangedEventArgs(nameof(ReactiveChildProp)); + + public partial string ChildProp + { + get => field; + set + { + if (!Equals(field, value)) + { + field = value; + OnPropertyChanged(_childPropChangedEventArgs); + } + } + } + + public partial string ReactiveChildProp + { + get => field; + set + { + if (!Equals(field, value)) + { + field = value; + OnPropertyChanged(_reactiveChildPropChangedEventArgs); + } + } + } + } +} + + }, + { + FileName: MainLib.GrandchildClass.ReactiveProperties.g.cs, + Source: +// +#nullable enable + +using System.ComponentModel; +using System.Runtime.CompilerServices; + +namespace MainLib +{ + /// + /// A partial class implementation for MainLib.GrandchildClass. + /// + public partial class GrandchildClass + { + private static readonly PropertyChangedEventArgs _reactiveGrandchildPropChangedEventArgs = new PropertyChangedEventArgs(nameof(ReactiveGrandchildProp)); + + public partial string ReactiveGrandchildProp + { + get => field; + set + { + if (!Equals(field, value)) + { + field = value; + OnPropertyChanged(_reactiveGrandchildPropChangedEventArgs); + } + } + } + } +} + + }, + { + FileName: ReactiveAttribute.g.cs, + Source: +using System; + +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = true, AllowMultiple = false)] +sealed class ReactiveAttribute : Attribute +{ + public ReactiveAttribute() { } +} + } + ], + Diagnostics: null +} \ No newline at end of file