├── .editorconfig
├── .gitattributes
├── .github
├── dependabot.yml
└── workflows
│ └── merge-dependabot.yml
├── .gitignore
├── Directory.Build.props
├── PropertyChanged.Fody.Analyzer.Tests
├── CodeGeneratorTest.CodeIsGeneratedForClassesInMultipleNamespaces.verified.txt
├── CodeGeneratorTest.CodeIsGeneratedForClassesNestedInRecord.verified.txt
├── CodeGeneratorTest.CodeIsGeneratedForClassesNestedInStruct.verified.txt
├── CodeGeneratorTest.CodeIsGeneratedForDeepNestedItems.verified.txt
├── CodeGeneratorTest.CodeIsGeneratedForNestedPartialClasses.verified.txt
├── CodeGeneratorTest.CodeIsGeneratedForPartialClassWithAttribute.verified.txt
├── CodeGeneratorTest.CodeIsGeneratedForPartialClassWithAttributeAndInterfaceAndBaseClass.verified.txt
├── CodeGeneratorTest.CodeIsGeneratedForPartialClassWithAttributeInFileScopedNamespace.verified.txt
├── CodeGeneratorTest.CodeIsGeneratedForPartialClassWithFullNameInterface.verified.txt
├── CodeGeneratorTest.CodeIsGeneratedForPartialClassWithRedundantInterfaceImplementation.verified.txt
├── CodeGeneratorTest.CodeIsGeneratedForPartialClassWithRedundantInterfaceImplementationAndAttributeButNotOnTheFirstPart.verified.txt
├── CodeGeneratorTest.CodeIsGeneratedForPartialClassWithoutEventHandler.verified.txt
├── CodeGeneratorTest.CodeIsGeneratedForPartialGenericClassWithAttribute.verified.txt
├── CodeGeneratorTest.CodeIsGeneratedForPartialGenericClassWithoutEventHandler.verified.txt
├── CodeGeneratorTest.CodeIsGeneratedNoneVirtualForSealedPartialClassWithAttribute.verified.txt
├── CodeGeneratorTest.NoCodeIsGeneratedForPartialClass2WithAttributeAndAttributedBaseClass.verified.txt
├── CodeGeneratorTest.NoCodeIsGeneratedForPartialClass2WithAttributeAndInterfaceImplementationInBaseClass.verified.txt
├── CodeGeneratorTest.cs
├── FodyWeavers.xml
├── FodyWeavers.xsd
├── GlobalUsings.cs
├── PropertyChanged.Fody.Analyzer.Tests.csproj
├── SourceGeneratorTest.cs
└── Usings.cs
├── PropertyChanged.Fody.Analyzer
├── AssemblyInfo.cs
├── CodeBlock.cs
├── CodeBuilder.cs
├── Configuration.cs
├── ExtensionMethods.cs
├── PropertyChanged.Fody.Analyzer.csproj
├── SourceGenerator.cs
├── SourceGeneratorEngine.cs
└── TypeContext.cs
├── PropertyChanged.Fody
├── AllPropertiesFinder.cs
├── AlreadyNotifyFinder.cs
├── AttributeCleaner.cs
├── CecilExtensions.cs
├── CodeGenTypeCleaner.cs
├── CollectionCustomAttributeExtension.cs
├── Config
│ ├── CheckForEqualityConfig.cs
│ ├── CheckForEqualityUsingBaseEqualsConfig.cs
│ ├── EnableIsChangedPropertyConfig.cs
│ ├── InjectOnPropertyNameChangedConfig.cs
│ ├── SuppressOnPropertyNameChangedWarningConfig.cs
│ ├── SuppressWarningsConfig.cs
│ ├── TriggerDependentPropertiesConfig.cs
│ └── UseStaticEqualsFromBaseConfig.cs
├── DelegateHolderInjector.cs
├── DependsOnDataAttributeReader.cs
├── DoNotNotifyTypeCleaner.cs
├── EqualityCheckWeaver.cs
├── EventArgsCache.cs
├── EventArgsCacheInjector.cs
├── EventInvokerMethod.cs
├── EventInvokerNameResolver.cs
├── FilterTypeDataAttributeReader.cs
├── HasEqualityChecker.cs
├── IlGeneratedByDependencyProcessor.cs
├── IlGeneratedByDependencyReader.cs
├── InstructionListExtensions.cs
├── InterceptorFinder.cs
├── InterfaceInjector.cs
├── InvokerTypes.cs
├── IsChangedMethodFinder.cs
├── MappingFinder.cs
├── MemberMapping.cs
├── MethodFinder.cs
├── MethodGenerifier.cs
├── MethodInjector.cs
├── MethodInterceptorInjector.cs
├── ModuleWeaver.cs
├── MsCoreReferenceFinder.cs
├── NotifyInterfaceFinder.cs
├── NotifyPropertyData.cs
├── NotifyPropertyDataAttributeReader.cs
├── OnChangedMethod.cs
├── OnChangedWalker.cs
├── PropertyChanged.Fody.csproj
├── PropertyChanged.Fody.xcf
├── PropertyChangedAddMethodFinder.cs
├── PropertyData.cs
├── PropertyDataWalker.cs
├── PropertyDependency.cs
├── PropertyWeaver.cs
├── RecursiveIlFinder.cs
├── ReturnFixer.cs
├── StackOverflowChecker.cs
├── SupportsCeqChecker.cs
├── TypeEqualityFinder.cs
├── TypeNode.cs
├── TypeNodeBuilder.cs
├── TypeProcessor.cs
├── TypeResolver.cs
└── WarningChecker.cs
├── PropertyChanged.sln
├── PropertyChanged.sln.DotSettings
├── PropertyChanged
├── AddINotifyPropertyChangedInterfaceAttribute.cs
├── AlsoNotifyForAttribute.cs
├── DependsOnAttribute.cs
├── DoNotCheckEqualityAttribute.cs
├── DoNotNotifyAttribute.cs
├── DoNotSetChangedAttribute.cs
├── FilterTypeAttribute.cs
├── ImplementPropertyChangedAttribute.cs
├── OnChangedMethodAttribute.cs
├── PropertyChanged.csproj
├── SuppressPropertyChangedWarningsAttribute.cs
├── Weaver.props
└── key.snk
├── SmokeTest
├── Classes.cs
├── CombinedChangingAndChangedWeaverTests.NullableValueTypeProperty.Debug.verified.il
├── CombinedChangingAndChangedWeaverTests.NullableValueTypeProperty.Release.verified.il
├── CombinedChangingAndChangedWeaverTests.ReferenceTypeProperty.Debug.verified.il
├── CombinedChangingAndChangedWeaverTests.ReferenceTypeProperty.Release.verified.il
├── CombinedChangingAndChangedWeaverTests.ValueTypeProperty.Debug.verified.il
├── CombinedChangingAndChangedWeaverTests.ValueTypeProperty.Release.verified.il
├── CombinedChangingAndChangedWeaverTests.cs
├── FodyWeavers.xml
├── FodyWeavers.xsd
├── PartialClasses.cs
└── SmokeTest.csproj
├── TestAssemblies
├── AssemblyExplicitPropertyChanged
│ ├── AssemblyExplicitPropertyChanged.csproj
│ └── ClassExplicitPropertyChanged.cs
├── AssemblyFSharp
│ ├── AssemblyFSharp.fsproj
│ ├── ClassWithNoOnPropertyChanged.fs
│ └── ClassWithProperties.fs
├── AssemblyInheritingBadNamedInvoker
│ ├── AssemblyInheritingBadNamedInvoker.csproj
│ └── ChildClass.cs
├── AssemblyToProcess
│ ├── AbstractProperty
│ │ ├── ClassWithAbstractProperty.cs
│ │ └── ClassWithPropertyImp.cs
│ ├── AssemblyToProcess.csproj
│ ├── BindableBaseTargets.cs
│ ├── ClassAlreadyHasNotification.cs
│ ├── ClassAlreadyHasSingleNotification.cs
│ ├── ClassAlreadyHasSingleNotificationDiffParamLocation.cs
│ ├── ClassAlreadyHasSingleNotificationDiffSignature.cs
│ ├── ClassAlsoNotifyFor.cs
│ ├── ClassAlsoNotifyForMultiple.cs
│ ├── ClassCircularProperties.cs
│ ├── ClassDependsOn.cs
│ ├── ClassDoNotCheckEquality.cs
│ ├── ClassDoNotCheckEqualityWholeClass.cs
│ ├── ClassEquality.cs
│ ├── ClassEqualityWithDouble.cs
│ ├── ClassEqualityWithGenericClassOverload.cs
│ ├── ClassEqualityWithGenericStructOverload.cs
│ ├── ClassEqualityWithStruct.cs
│ ├── ClassEqualityWithStructOverload.cs
│ ├── ClassMissingSetGet.cs
│ ├── ClassNoBackingNoEqualityField.cs
│ ├── ClassNoBackingWithEqualityField.cs
│ ├── ClassSetterEndsOnThrowInRelease.cs
│ ├── ClassStaticProperties.cs
│ ├── ClassThatIsNotSealed.cs
│ ├── ClassThatIsSealed.cs
│ ├── ClassWithAlsoNotifyFor.cs
│ ├── ClassWithBeforeAfterAndSimpleImplementation.cs
│ ├── ClassWithBeforeAfterImplementation.cs
│ ├── ClassWithBeforeAfterImplementationMissingSetGet.cs
│ ├── ClassWithBeforeAfterValueCheckImplementation.cs
│ ├── ClassWithBoolPropUsingStringProp.cs
│ ├── ClassWithBranchingReturn1.cs
│ ├── ClassWithBranchingReturn2.cs
│ ├── ClassWithBranchingReturnAndBeforeAfter.cs
│ ├── ClassWithBranchingReturnAndNoField.cs
│ ├── ClassWithCustomPropertyChanged.cs
│ ├── ClassWithDependencyAfterSet.cs
│ ├── ClassWithDependsOn.cs
│ ├── ClassWithDependsOnAndDoNotNotify.cs
│ ├── ClassWithDependsOnAndPropertyChanged.cs
│ ├── ClassWithDoNotNotify.cs
│ ├── ClassWithDoNotNotifyField.cs
│ ├── ClassWithDoNotSetChanged.cs
│ ├── ClassWithExceptionInProperty.cs
│ ├── ClassWithExplicitPropertyChanged.cs
│ ├── ClassWithExpression.cs
│ ├── ClassWithFieldGetButNoFieldSet.cs
│ ├── ClassWithGeneratedPropertyChanged.cs
│ ├── ClassWithGenericAndLambda.cs
│ ├── ClassWithGenericStructProp
│ │ ├── ClassWithGenericStructProp.cs
│ │ └── ClassWithGenericStructPropImpl.cs
│ ├── ClassWithIndexer.cs
│ ├── ClassWithIndexerDependsOnAndBeforeAfter.cs
│ ├── ClassWithIndexerReferencingPropertyAndBeforeAfter.cs
│ ├── ClassWithIndirectImplementation.cs
│ ├── ClassWithInferredShouldAlsoNotifyFor.cs
│ ├── ClassWithInvalidIsChangedType.cs
│ ├── ClassWithInvalidOnChanged.cs
│ ├── ClassWithIsChanged.cs
│ ├── ClassWithLdflda.cs
│ ├── ClassWithLdfldaShortCircuit.cs
│ ├── ClassWithLogicInSet.cs
│ ├── ClassWithNested.cs
│ ├── ClassWithNotifyPropertyChangedAttribute.cs
│ ├── ClassWithNotifyPropertyChangedAttributeChild.cs
│ ├── ClassWithNotifyPropertyChangedAttributeChildParent.cs
│ ├── ClassWithNullableBackingField.cs
│ ├── ClassWithNullableGenericStruct.cs
│ ├── ClassWithOnChanged.cs
│ ├── ClassWithOnChangedAbstract.cs
│ ├── ClassWithOnChangedAndNoPropertyChanged.cs
│ ├── ClassWithOnChangedAndOnPropertyChanged.cs
│ ├── ClassWithOnChangedBeforeAfter.cs
│ ├── ClassWithOnChangedBeforeAfterCalculatedProperty.cs
│ ├── ClassWithOnChangedBeforeAfterGeneric.cs
│ ├── ClassWithOnChangedBeforeAfterTyped.cs
│ ├── ClassWithOnChangedCalculatedProperty.cs
│ ├── ClassWithOnChangedCustomized.cs
│ ├── ClassWithOnChangedSuppressed.cs
│ ├── ClassWithOpenGenerics.cs
│ ├── ClassWithOwnImplementation.cs
│ ├── ClassWithPropertyChangedArgImplementation.cs
│ ├── ClassWithPropertySetInCatch.cs
│ ├── ClassWithSenderPropertyChangedArgImplementation.cs
│ ├── ClassWithSetterThatThrows.cs
│ ├── ClassWithTaskReturningPropertyChangedNotifier.cs
│ ├── ClassWithTernary.cs
│ ├── ClassWithTryCatchInSet.cs
│ ├── ClassWithWarnings.cs
│ ├── CodeGenAttribute
│ │ ├── ClassWithCompilerGeneratedAttribute.cs
│ │ └── ClassWithGeneratedCodeAttribute.cs
│ ├── ComplexHierarchy
│ │ ├── ClassChild1.cs
│ │ ├── ClassChild2.cs
│ │ ├── ClassChild3.cs
│ │ └── ClassParent.cs
│ ├── FieldsFromOtherClass
│ │ ├── ClassWithFieldFromOtherClass.cs
│ │ └── OtherClass.cs
│ ├── GenericBase
│ │ ├── ClassWithGenericChild.cs
│ │ ├── ClassWithGenericParent.cs
│ │ ├── ClassWithIntermediateGenericBase.cs
│ │ └── IntermediateGenericClass.cs
│ ├── GenericBaseWithProperty
│ │ ├── ClassWithGenericProperty.cs
│ │ └── ClassWithGenericPropertyChild.cs
│ ├── GenericBaseWithPropertyBeforeAfter
│ │ ├── ClassWithGenericProperty.cs
│ │ └── ClassWithGenericPropertyChild.cs
│ ├── GenericBaseWithPropertyOnChanged
│ │ ├── ClassWithGenericProperty.cs
│ │ └── ClassWithGenericPropertyChild.cs
│ ├── GenericChildWithProperty
│ │ ├── ClassWithGenericProperty.cs
│ │ └── ClassWithGenericPropertyChild.cs
│ ├── GenericChildWithPropertyBeforeAfter
│ │ ├── ClassWithGenericProperty.cs
│ │ └── ClassWithGenericPropertyChild.cs
│ ├── GenericChildWithPropertyOnChanged
│ │ ├── ClassWithGenericProperty.cs
│ │ └── ClassWithGenericPropertyChild.cs
│ ├── GenericMiddle
│ │ ├── ClassWithGenericMiddle.cs
│ │ ├── ClassWithGenericMiddleBase.cs
│ │ └── ClassWithGenericMiddleChild.cs
│ ├── HierarchyBeforeAfterAndSimple
│ │ ├── ClassBase.cs
│ │ └── ClassChild.cs
│ ├── InterfaceWithAttributes.cs
│ ├── NotifyInBase
│ │ ├── ClassParentWithProperty.cs
│ │ └── ClassWithNotifyInBase.cs
│ ├── NotifyInChild
│ │ ├── ClassWithNotifyInChildByAttribute.cs
│ │ ├── ClassWithNotifyInChildByInterface.cs
│ │ └── ParentClass.cs
│ ├── OnceRemovedINotify
│ │ ├── ClassWithOnceRemovedINotify.cs
│ │ └── INotifyPropertyChangedChild.cs
│ ├── StructWithAttributes.cs
│ ├── StructWithNotify.cs
│ ├── SupportedLibraries
│ │ ├── BaseClasses.cs
│ │ ├── ClassCaliburn.cs
│ │ ├── ClassCaliburnMicro.cs
│ │ ├── ClassCaliburnOverriddenInvoker.cs
│ │ ├── ClassCatel.cs
│ │ ├── ClassReactiveUI.cs
│ │ └── ClassTelerik.cs
│ ├── TransitiveDependencies.cs
│ ├── UsingPublicFieldThroughParameter
│ │ ├── ClassUsingPublicFieldThroughParameter.cs
│ │ └── ClassWithPublicField.cs
│ ├── WithInitializedProperties
│ │ ├── ClassWithAutoPropertiesInitializedInSeparateMethod.cs
│ │ ├── ClassWithExplicitInitializedAutoProperties.cs
│ │ ├── ClassWithExplicitInitializedAutoPropertiesDerivedProperDesign.cs
│ │ ├── ClassWithExplicitInitializedAutoPropertiesDerivedWeakDesign.cs
│ │ ├── ClassWithExplicitInitializedBackingFieldProperties.cs
│ │ ├── ClassWithInlineInitializedAutoProperties.cs
│ │ └── ObservableTestObject.cs
│ └── WithOwnIsChangedImplementation
│ │ ├── WithOwnIsChangedImplementation.cs
│ │ └── WithOwnIsChangedImplementationInherited.cs
├── AssemblyWithAttributeAndEvent
│ ├── AssemblyWithAttributeAndEvent.csproj
│ └── ClassWithAttributeAndEvent.cs
├── AssemblyWithBadNamedInvoker
│ ├── AssemblyWithBadNamedInvoker.csproj
│ └── BaseClass.cs
├── AssemblyWithBase
│ ├── AssemblyWithBase.csproj
│ ├── BaseWithEquals
│ │ └── BaseClass1.cs
│ ├── BaseWithGenericParent
│ │ ├── BaseClass1.cs
│ │ └── BaseClass2.cs
│ ├── DirectGeneric
│ │ └── BaseClass.cs
│ ├── GenericFromAbove
│ │ ├── BaseClass1.cs
│ │ └── BaseClass2.cs
│ ├── GenericMiddle
│ │ ├── BaseClassWithGenericMiddle.cs
│ │ └── BaseClassWithGenericMiddleBase.cs
│ ├── MultiTypes
│ │ ├── BaseClass1.cs
│ │ └── BaseClass2.cs
│ ├── Simple
│ │ ├── BaseClass.cs
│ │ └── BaseClassWithVirtualProperty.cs
│ ├── StaticEquals
│ │ └── BaseClass.cs
│ └── StaticEqualsGenericParent
│ │ ├── BaseClass.cs
│ │ ├── BaseClass2.cs
│ │ ├── BaseClass3.cs
│ │ ├── ClassUsingBase.cs
│ │ ├── ClassWithOwnEquals.cs
│ │ ├── ClassWithTwoBaseClasses1.cs
│ │ └── ClassWithTwoBaseClasses2.cs
├── AssemblyWithBaseInDifferentModule
│ ├── AssemblyWithBaseInDifferentModule.csproj
│ ├── BaseWithGenericParent
│ │ └── ChildClass.cs
│ ├── BaseWithGenericProperty
│ │ └── Class.cs
│ ├── DirectGeneric
│ │ └── ChildClass.cs
│ ├── GenericFromAbove
│ │ └── ChildClass.cs
│ ├── GenericMiddle
│ │ └── ClassWithGenericMiddleChildInDifferentModule.cs
│ ├── Hierarchy
│ │ ├── ChildClass.cs
│ │ └── StaticEquals.cs
│ ├── MultiTypes
│ │ └── ChildClass.cs
│ ├── Simple
│ │ └── ChildClass.cs
│ ├── StaticEquals
│ │ └── StaticEquals.cs
│ └── StaticEqualsGenericParent
│ │ ├── ArgsMapping1.cs
│ │ ├── ArgsMapping2.cs
│ │ ├── OwnStaticEquals.cs
│ │ ├── StaticEquals.cs
│ │ └── StaticEqualsOnBase.cs
├── AssemblyWithBeforeAfterInterceptor
│ ├── AssemblyWithBeforeAfterInterceptor.csproj
│ ├── ClassToTest.cs
│ └── PropertyNotificationInterceptor.cs
├── AssemblyWithBlockingClass
│ ├── AssemblyWithBlockingClass.csproj
│ └── Classes.cs
├── AssemblyWithDisabledInjectOnPropertyNameChanged
│ ├── AssemblyWithDisabledInjectOnPropertyNameChanged.csproj
│ ├── ClassWithConfiguredOnPropertyChanged.cs
│ └── ClassWithOnPropertyChangedMethod.cs
├── AssemblyWithDisabledIsChangedProperty
│ ├── AssemblyWithDisabledIsChangedProperty.csproj
│ └── IsChangedClassToTest.cs
├── AssemblyWithDisabledTriggerDependentProperties
│ ├── AssemblyWithDisabledTriggerDependentProperties.csproj
│ └── DependentPropertiesClassToTest.cs
├── AssemblyWithExternalInheritance
│ ├── AssemblyWithExternalInheritance.csproj
│ └── Classes.cs
├── AssemblyWithInheritance
│ ├── AssemblyWithInheritance.csproj
│ └── Classes.cs
├── AssemblyWithInterceptor
│ ├── AssemblyWithInterceptor.csproj
│ ├── ClassToTest.cs
│ └── PropertyNotificationInterceptor.cs
├── AssemblyWithNonVoidOnPropertyNameChanged
│ ├── AssemblyWithNonVoidOnPropertyNameChanged.csproj
│ └── ClassWithNonVoidOnPropertyChanged.cs
├── AssemblyWithStackOverflow
│ ├── AssemblyWithStackOverflow.csproj
│ ├── BaseClass.cs
│ ├── ChildClass.cs
│ ├── ChildWithBaseInDifferentAssembly.cs
│ └── ClassWithStackOverflow.cs
├── AssemblyWithStaticOnPropertyNameChanged
│ ├── AssemblyWithStaticOnPropertyNameChanged.csproj
│ └── ClassWithNonVoidOnPropertyChanged.cs
└── AssemblyWithTypeFilter
│ ├── AssemblyInfo.cs
│ ├── AssemblyWithTypeFilter.csproj
│ ├── PropertyChangedNotificationInterceptor.cs
│ ├── TestClassExclude.cs
│ ├── TestClassInclude.cs
│ └── TestClassIncludeAlso.cs
├── Tests
├── AlreadyNotifyFinderTest.cs
├── AssemblyExplicitPropertyChanged.cs
├── AssemblyToProcessTests.cs
├── AssemblyWithAttributeAndEventTests.cs
├── AssemblyWithBadNamedInvokerTests.cs
├── AssemblyWithBaseInDifferentModuleTests.cs
├── AssemblyWithBlockingClassTests.cs
├── AssemblyWithDisabledInjectOnPropertyNameChangedTests.cs
├── AssemblyWithDisabledIsChangedPropertyTests.cs
├── AssemblyWithDisabledTriggerDependentPropertiesTests.cs
├── AssemblyWithInheritanceTests.cs
├── AssemblyWithInterceptorTests.cs
├── AssemblyWithNonVoidOnPropertyChangedTests.Simple.verified.txt
├── AssemblyWithNonVoidOnPropertyChangedTests.cs
├── AttributeReaders
│ └── DependsOnDataAttributeReaderTests.cs
├── CheckForEqualityConfigTests.cs
├── CheckForEqualityUsingBaseEqualsConfigTests.cs
├── DefinitionFinder.cs
├── EventInvokerNamesConfigTests.cs
├── EventTester.cs
├── Extensions.cs
├── FSharpTest.cs
├── GlobalUsings.cs
├── HasEqualityCheckerTests.cs
├── IlGeneratedByDependencyReaderTests
│ ├── WithAutoProperties.cs
│ ├── WithCamelCaseFields.cs
│ ├── WithDoNotNotifyProperty.cs
│ ├── WithGenericAutoProperties.cs
│ ├── WithGenericFields.cs
│ ├── WithLambda.cs
│ ├── WithUnderScoreFields.cs
│ ├── WithUpperCaseUnderScoreFields.cs
│ └── WithVirtualAutoProperties.cs
├── InjectOnPropertyNameChangedTests.ModuleWeaver_WhenInjectOnPropertyNameChangedIsTrue_WarnsForNonVoidMethods.verified.txt
├── InjectOnPropertyNameChangedTests.ModuleWeaver_WhenInjectOnPropertyNameChangedIsTrue_WarnsForStaticMethods.verified.txt
├── InjectOnPropertyNameChangedTests.cs
├── MappingFinder
│ ├── MappingFinderAutoPropertiesAndDodgyField.cs
│ ├── MappingFinderInnerClass.cs
│ ├── MappingFinderLowerCaseBackingFields.cs
│ ├── MappingFinderSingleBackingConstantFieldGet.cs
│ ├── MappingFinderSingleBackingFieldsGet.cs
│ ├── MappingFinderSingleBackingFieldsSet.cs
│ ├── MappingFinderSingleBackingReadonlyFieldGet.cs
│ ├── MappingFinderUnderScoreBackingFields.cs
│ └── MappingFinderWithAutoProperties.cs
├── MethodFinderTest.cs
├── MethodInjectorTests.cs
├── OnPropertyNameChangedConfigTests.cs
├── PropertyInfoCheckers
│ ├── AbstractInfoCheckerTest.cs
│ ├── BeforeAfterWithNoGetInfoCheckerTest.cs
│ ├── CheckForEqualityWithNoBackingFieldSetInfoCheckerTest.cs
│ ├── IndexerCheckerTest.cs
│ └── PropertyChangedArgWithNoGetInfoCheckerTest.cs
├── RecursiveIlFinderTests.cs
├── StackOverflowCheckerTests.cs
├── SuppressOnPropertyNameChangedWarningConfigTests.cs
├── SuppressWarningsConfigTests.cs
├── Tests.csproj
├── TriggerDependentPropertiesConfigTests.cs
├── TypeEqualityFinderTests.cs
└── TypeFilterTests.cs
├── appveyor.yml
├── global.json
├── license.txt
├── nuget.config
├── package_icon.png
└── readme.md
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Auto detect text files and perform LF normalization
2 | * text
3 |
4 | # Don't check these into the repo as LF to work around TeamCity bug
5 | *.xml -text
6 | *.targets -text
7 |
8 | # Custom for Visual Studio
9 | *.cs diff=csharp
10 | *.sln merge=union
11 | *.csproj merge=union
12 | *.vbproj merge=union
13 | *.fsproj merge=union
14 | *.dbproj merge=union
15 |
16 | # Denote all files that are truly binary and should not be modified.
17 | *.dll binary
18 | *.exe binary
19 | *.png binary
20 | *.ico binary
21 | *.snk binary
22 | *.pdb binary
23 | *.svg binary
24 |
--------------------------------------------------------------------------------
/.github/dependabot.yml:
--------------------------------------------------------------------------------
1 | version: 2
2 | updates:
3 | - package-ecosystem: nuget
4 | directory: "/"
5 | schedule:
6 | interval: daily
7 | open-pull-requests-limit: 10
--------------------------------------------------------------------------------
/.github/workflows/merge-dependabot.yml:
--------------------------------------------------------------------------------
1 | name: merge-dependabot
2 | on:
3 | pull_request:
4 | jobs:
5 | automerge:
6 | runs-on: ubuntu-latest
7 | if: github.actor == 'dependabot[bot]'
8 | steps:
9 | - name: Dependabot Auto Merge
10 | uses: ahmadnassri/action-dependabot-auto-merge@v2.6.6
11 | with:
12 | target: minor
13 | github-token: ${{ secrets.GITHUB_TOKEN }}
14 | command: squash and merge
--------------------------------------------------------------------------------
/Directory.Build.props:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | true
5 | 4.1.0
6 | preview
7 | NU5118
8 | true
9 | all
10 | low
11 |
12 |
13 |
--------------------------------------------------------------------------------
/PropertyChanged.Fody.Analyzer.Tests/CodeGeneratorTest.CodeIsGeneratedForClassesNestedInRecord.verified.txt:
--------------------------------------------------------------------------------
1 | // PropertyChanged.g.cs
2 | //
3 | #nullable enable
4 | #pragma warning disable CS0067
5 | #pragma warning disable CS8019
6 | using System.Diagnostics;
7 | using System.CodeDom.Compiler;
8 | using System.ComponentModel;
9 | using System.Runtime.CompilerServices;
10 |
11 | partial record Class1
12 | {
13 | partial class Class2
14 | {
15 | [GeneratedCode("PropertyChanged.Fody", "TEST")]
16 | public event PropertyChangedEventHandler? PropertyChanged;
17 |
18 | [GeneratedCode("PropertyChanged.Fody", "TEST"), DebuggerNonUserCode]
19 | protected void OnPropertyChanged([CallerMemberName] string? propertyName = null)
20 | {
21 | OnPropertyChanged(new PropertyChangedEventArgs(propertyName));
22 | }
23 |
24 | [GeneratedCode("PropertyChanged.Fody", "TEST"), DebuggerNonUserCode]
25 | protected virtual void OnPropertyChanged(PropertyChangedEventArgs eventArgs)
26 | {
27 | PropertyChanged?.Invoke(this, eventArgs);
28 | }
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/PropertyChanged.Fody.Analyzer.Tests/CodeGeneratorTest.CodeIsGeneratedForClassesNestedInStruct.verified.txt:
--------------------------------------------------------------------------------
1 | // PropertyChanged.g.cs
2 | //
3 | #nullable enable
4 | #pragma warning disable CS0067
5 | #pragma warning disable CS8019
6 | using System.Diagnostics;
7 | using System.CodeDom.Compiler;
8 | using System.ComponentModel;
9 | using System.Runtime.CompilerServices;
10 |
11 | partial struct Class1
12 | {
13 | partial class Class2
14 | {
15 | [GeneratedCode("PropertyChanged.Fody", "TEST")]
16 | public event PropertyChangedEventHandler? PropertyChanged;
17 |
18 | [GeneratedCode("PropertyChanged.Fody", "TEST"), DebuggerNonUserCode]
19 | protected void OnPropertyChanged([CallerMemberName] string? propertyName = null)
20 | {
21 | OnPropertyChanged(new PropertyChangedEventArgs(propertyName));
22 | }
23 |
24 | [GeneratedCode("PropertyChanged.Fody", "TEST"), DebuggerNonUserCode]
25 | protected virtual void OnPropertyChanged(PropertyChangedEventArgs eventArgs)
26 | {
27 | PropertyChanged?.Invoke(this, eventArgs);
28 | }
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/PropertyChanged.Fody.Analyzer.Tests/CodeGeneratorTest.CodeIsGeneratedForPartialClassWithAttribute.verified.txt:
--------------------------------------------------------------------------------
1 | // PropertyChanged.g.cs
2 | //
3 | #nullable enable
4 | #pragma warning disable CS0067
5 | #pragma warning disable CS8019
6 | using System.Diagnostics;
7 | using System.CodeDom.Compiler;
8 | using System.ComponentModel;
9 | using System.Runtime.CompilerServices;
10 |
11 | partial class Class1 : INotifyPropertyChanged
12 | {
13 | [GeneratedCode("PropertyChanged.Fody", "TEST")]
14 | public event PropertyChangedEventHandler? PropertyChanged;
15 |
16 | [GeneratedCode("PropertyChanged.Fody", "TEST"), DebuggerNonUserCode]
17 | protected void OnPropertyChanged([CallerMemberName] string? propertyName = null)
18 | {
19 | OnPropertyChanged(new PropertyChangedEventArgs(propertyName));
20 | }
21 |
22 | [GeneratedCode("PropertyChanged.Fody", "TEST"), DebuggerNonUserCode]
23 | protected virtual void OnPropertyChanged(PropertyChangedEventArgs eventArgs)
24 | {
25 | PropertyChanged?.Invoke(this, eventArgs);
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/PropertyChanged.Fody.Analyzer.Tests/CodeGeneratorTest.CodeIsGeneratedForPartialClassWithAttributeAndInterfaceAndBaseClass.verified.txt:
--------------------------------------------------------------------------------
1 | // PropertyChanged.g.cs
2 | //
3 | #nullable enable
4 | #pragma warning disable CS0067
5 | #pragma warning disable CS8019
6 | using System.Diagnostics;
7 | using System.CodeDom.Compiler;
8 | using System.ComponentModel;
9 | using System.Runtime.CompilerServices;
10 |
11 | partial class Class1
12 | {
13 | [GeneratedCode("PropertyChanged.Fody", "TEST")]
14 | public event PropertyChangedEventHandler? PropertyChanged;
15 |
16 | [GeneratedCode("PropertyChanged.Fody", "TEST"), DebuggerNonUserCode]
17 | protected void OnPropertyChanged([CallerMemberName] string? propertyName = null)
18 | {
19 | OnPropertyChanged(new PropertyChangedEventArgs(propertyName));
20 | }
21 |
22 | [GeneratedCode("PropertyChanged.Fody", "TEST"), DebuggerNonUserCode]
23 | protected virtual void OnPropertyChanged(PropertyChangedEventArgs eventArgs)
24 | {
25 | PropertyChanged?.Invoke(this, eventArgs);
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/PropertyChanged.Fody.Analyzer.Tests/CodeGeneratorTest.CodeIsGeneratedForPartialClassWithAttributeInFileScopedNamespace.verified.txt:
--------------------------------------------------------------------------------
1 | // PropertyChanged.g.cs
2 | //
3 | #nullable enable
4 | #pragma warning disable CS0067
5 | #pragma warning disable CS8019
6 | using System.Diagnostics;
7 | using System.CodeDom.Compiler;
8 | using System.ComponentModel;
9 | using System.Runtime.CompilerServices;
10 |
11 | namespace Whatever
12 | {
13 | partial class Class1 : INotifyPropertyChanged
14 | {
15 | [GeneratedCode("PropertyChanged.Fody", "TEST")]
16 | public event PropertyChangedEventHandler? PropertyChanged;
17 |
18 | [GeneratedCode("PropertyChanged.Fody", "TEST"), DebuggerNonUserCode]
19 | protected void OnPropertyChanged([CallerMemberName] string? propertyName = null)
20 | {
21 | OnPropertyChanged(new PropertyChangedEventArgs(propertyName));
22 | }
23 |
24 | [GeneratedCode("PropertyChanged.Fody", "TEST"), DebuggerNonUserCode]
25 | protected virtual void OnPropertyChanged(PropertyChangedEventArgs eventArgs)
26 | {
27 | PropertyChanged?.Invoke(this, eventArgs);
28 | }
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/PropertyChanged.Fody.Analyzer.Tests/CodeGeneratorTest.CodeIsGeneratedForPartialClassWithFullNameInterface.verified.txt:
--------------------------------------------------------------------------------
1 | // PropertyChanged.g.cs
2 | //
3 | #nullable enable
4 | #pragma warning disable CS0067
5 | #pragma warning disable CS8019
6 | using System.Diagnostics;
7 | using System.CodeDom.Compiler;
8 | using System.ComponentModel;
9 | using System.Runtime.CompilerServices;
10 |
11 | partial class Class1
12 | {
13 | [GeneratedCode("PropertyChanged.Fody", "TEST")]
14 | public event PropertyChangedEventHandler? PropertyChanged;
15 |
16 | [GeneratedCode("PropertyChanged.Fody", "TEST"), DebuggerNonUserCode]
17 | protected void OnPropertyChanged([CallerMemberName] string? propertyName = null)
18 | {
19 | OnPropertyChanged(new PropertyChangedEventArgs(propertyName));
20 | }
21 |
22 | [GeneratedCode("PropertyChanged.Fody", "TEST"), DebuggerNonUserCode]
23 | protected virtual void OnPropertyChanged(PropertyChangedEventArgs eventArgs)
24 | {
25 | PropertyChanged?.Invoke(this, eventArgs);
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/PropertyChanged.Fody.Analyzer.Tests/CodeGeneratorTest.CodeIsGeneratedForPartialClassWithRedundantInterfaceImplementation.verified.txt:
--------------------------------------------------------------------------------
1 | // PropertyChanged.g.cs
2 | //
3 | #nullable enable
4 | #pragma warning disable CS0067
5 | #pragma warning disable CS8019
6 | using System.Diagnostics;
7 | using System.CodeDom.Compiler;
8 | using System.ComponentModel;
9 | using System.Runtime.CompilerServices;
10 |
11 | partial class Class1
12 | {
13 | [GeneratedCode("PropertyChanged.Fody", "TEST")]
14 | public event PropertyChangedEventHandler? PropertyChanged;
15 |
16 | [GeneratedCode("PropertyChanged.Fody", "TEST"), DebuggerNonUserCode]
17 | protected void OnPropertyChanged([CallerMemberName] string? propertyName = null)
18 | {
19 | OnPropertyChanged(new PropertyChangedEventArgs(propertyName));
20 | }
21 |
22 | [GeneratedCode("PropertyChanged.Fody", "TEST"), DebuggerNonUserCode]
23 | protected virtual void OnPropertyChanged(PropertyChangedEventArgs eventArgs)
24 | {
25 | PropertyChanged?.Invoke(this, eventArgs);
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/PropertyChanged.Fody.Analyzer.Tests/CodeGeneratorTest.CodeIsGeneratedForPartialClassWithRedundantInterfaceImplementationAndAttributeButNotOnTheFirstPart.verified.txt:
--------------------------------------------------------------------------------
1 | // PropertyChanged.g.cs
2 | //
3 | #nullable enable
4 | #pragma warning disable CS0067
5 | #pragma warning disable CS8019
6 | using System.Diagnostics;
7 | using System.CodeDom.Compiler;
8 | using System.ComponentModel;
9 | using System.Runtime.CompilerServices;
10 |
11 | partial class Class1234
12 | {
13 | [GeneratedCode("PropertyChanged.Fody", "TEST")]
14 | public event PropertyChangedEventHandler? PropertyChanged;
15 |
16 | [GeneratedCode("PropertyChanged.Fody", "TEST"), DebuggerNonUserCode]
17 | protected void OnPropertyChanged([CallerMemberName] string? propertyName = null)
18 | {
19 | OnPropertyChanged(new PropertyChangedEventArgs(propertyName));
20 | }
21 |
22 | [GeneratedCode("PropertyChanged.Fody", "TEST"), DebuggerNonUserCode]
23 | protected virtual void OnPropertyChanged(PropertyChangedEventArgs eventArgs)
24 | {
25 | PropertyChanged?.Invoke(this, eventArgs);
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/PropertyChanged.Fody.Analyzer.Tests/CodeGeneratorTest.CodeIsGeneratedForPartialClassWithoutEventHandler.verified.txt:
--------------------------------------------------------------------------------
1 | // PropertyChanged.g.cs
2 | //
3 | #nullable enable
4 | #pragma warning disable CS0067
5 | #pragma warning disable CS8019
6 | using System.Diagnostics;
7 | using System.CodeDom.Compiler;
8 | using System.ComponentModel;
9 | using System.Runtime.CompilerServices;
10 |
11 | partial class Class1
12 | {
13 | [GeneratedCode("PropertyChanged.Fody", "TEST")]
14 | public event PropertyChangedEventHandler? PropertyChanged;
15 |
16 | [GeneratedCode("PropertyChanged.Fody", "TEST"), DebuggerNonUserCode]
17 | protected void OnPropertyChanged([CallerMemberName] string? propertyName = null)
18 | {
19 | OnPropertyChanged(new PropertyChangedEventArgs(propertyName));
20 | }
21 |
22 | [GeneratedCode("PropertyChanged.Fody", "TEST"), DebuggerNonUserCode]
23 | protected virtual void OnPropertyChanged(PropertyChangedEventArgs eventArgs)
24 | {
25 | PropertyChanged?.Invoke(this, eventArgs);
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/PropertyChanged.Fody.Analyzer.Tests/CodeGeneratorTest.CodeIsGeneratedForPartialGenericClassWithAttribute.verified.txt:
--------------------------------------------------------------------------------
1 | // PropertyChanged.g.cs
2 | //
3 | #nullable enable
4 | #pragma warning disable CS0067
5 | #pragma warning disable CS8019
6 | using System.Diagnostics;
7 | using System.CodeDom.Compiler;
8 | using System.ComponentModel;
9 | using System.Runtime.CompilerServices;
10 |
11 | partial class Class1 : INotifyPropertyChanged
12 | {
13 | [GeneratedCode("PropertyChanged.Fody", "TEST")]
14 | public event PropertyChangedEventHandler? PropertyChanged;
15 |
16 | [GeneratedCode("PropertyChanged.Fody", "TEST"), DebuggerNonUserCode]
17 | protected void OnPropertyChanged([CallerMemberName] string? propertyName = null)
18 | {
19 | OnPropertyChanged(new PropertyChangedEventArgs(propertyName));
20 | }
21 |
22 | [GeneratedCode("PropertyChanged.Fody", "TEST"), DebuggerNonUserCode]
23 | protected virtual void OnPropertyChanged(PropertyChangedEventArgs eventArgs)
24 | {
25 | PropertyChanged?.Invoke(this, eventArgs);
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/PropertyChanged.Fody.Analyzer.Tests/CodeGeneratorTest.CodeIsGeneratedForPartialGenericClassWithoutEventHandler.verified.txt:
--------------------------------------------------------------------------------
1 | // PropertyChanged.g.cs
2 | //
3 | #nullable enable
4 | #pragma warning disable CS0067
5 | #pragma warning disable CS8019
6 | using System.Diagnostics;
7 | using System.CodeDom.Compiler;
8 | using System.ComponentModel;
9 | using System.Runtime.CompilerServices;
10 |
11 | partial class Class1
12 | {
13 | [GeneratedCode("PropertyChanged.Fody", "TEST")]
14 | public event PropertyChangedEventHandler? PropertyChanged;
15 |
16 | [GeneratedCode("PropertyChanged.Fody", "TEST"), DebuggerNonUserCode]
17 | protected void OnPropertyChanged([CallerMemberName] string? propertyName = null)
18 | {
19 | OnPropertyChanged(new PropertyChangedEventArgs(propertyName));
20 | }
21 |
22 | [GeneratedCode("PropertyChanged.Fody", "TEST"), DebuggerNonUserCode]
23 | protected virtual void OnPropertyChanged(PropertyChangedEventArgs eventArgs)
24 | {
25 | PropertyChanged?.Invoke(this, eventArgs);
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/PropertyChanged.Fody.Analyzer.Tests/CodeGeneratorTest.CodeIsGeneratedNoneVirtualForSealedPartialClassWithAttribute.verified.txt:
--------------------------------------------------------------------------------
1 | // PropertyChanged.g.cs
2 | //
3 | #nullable enable
4 | #pragma warning disable CS0067
5 | #pragma warning disable CS8019
6 | using System.Diagnostics;
7 | using System.CodeDom.Compiler;
8 | using System.ComponentModel;
9 | using System.Runtime.CompilerServices;
10 |
11 | partial class Class1 : INotifyPropertyChanged
12 | {
13 | [GeneratedCode("PropertyChanged.Fody", "TEST")]
14 | public event PropertyChangedEventHandler? PropertyChanged;
15 |
16 | [GeneratedCode("PropertyChanged.Fody", "TEST"), DebuggerNonUserCode]
17 | private void OnPropertyChanged([CallerMemberName] string? propertyName = null)
18 | {
19 | PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
20 | }
21 |
22 | [GeneratedCode("PropertyChanged.Fody", "TEST"), DebuggerNonUserCode]
23 | private void OnPropertyChanged(PropertyChangedEventArgs eventArgs)
24 | {
25 | PropertyChanged?.Invoke(this, eventArgs);
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/PropertyChanged.Fody.Analyzer.Tests/CodeGeneratorTest.NoCodeIsGeneratedForPartialClass2WithAttributeAndAttributedBaseClass.verified.txt:
--------------------------------------------------------------------------------
1 | // PropertyChanged.g.cs
2 | //
3 | #nullable enable
4 | #pragma warning disable CS0067
5 | #pragma warning disable CS8019
6 | using System.Diagnostics;
7 | using System.CodeDom.Compiler;
8 | using System.ComponentModel;
9 | using System.Runtime.CompilerServices;
10 |
11 | partial class Class1 : INotifyPropertyChanged
12 | {
13 | [GeneratedCode("PropertyChanged.Fody", "TEST")]
14 | public event PropertyChangedEventHandler? PropertyChanged;
15 |
16 | [GeneratedCode("PropertyChanged.Fody", "TEST"), DebuggerNonUserCode]
17 | protected void OnPropertyChanged([CallerMemberName] string? propertyName = null)
18 | {
19 | OnPropertyChanged(new PropertyChangedEventArgs(propertyName));
20 | }
21 |
22 | [GeneratedCode("PropertyChanged.Fody", "TEST"), DebuggerNonUserCode]
23 | protected virtual void OnPropertyChanged(PropertyChangedEventArgs eventArgs)
24 | {
25 | PropertyChanged?.Invoke(this, eventArgs);
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/PropertyChanged.Fody.Analyzer.Tests/CodeGeneratorTest.NoCodeIsGeneratedForPartialClass2WithAttributeAndInterfaceImplementationInBaseClass.verified.txt:
--------------------------------------------------------------------------------
1 | // PropertyChanged.g.cs
2 | //
3 | #nullable enable
4 | #pragma warning disable CS0067
5 | #pragma warning disable CS8019
6 | using System.Diagnostics;
7 | using System.CodeDom.Compiler;
8 | using System.ComponentModel;
9 | using System.Runtime.CompilerServices;
10 |
11 | partial class Class1
12 | {
13 | [GeneratedCode("PropertyChanged.Fody", "TEST")]
14 | public event PropertyChangedEventHandler? PropertyChanged;
15 |
16 | [GeneratedCode("PropertyChanged.Fody", "TEST"), DebuggerNonUserCode]
17 | protected void OnPropertyChanged([CallerMemberName] string? propertyName = null)
18 | {
19 | OnPropertyChanged(new PropertyChangedEventArgs(propertyName));
20 | }
21 |
22 | [GeneratedCode("PropertyChanged.Fody", "TEST"), DebuggerNonUserCode]
23 | protected virtual void OnPropertyChanged(PropertyChangedEventArgs eventArgs)
24 | {
25 | PropertyChanged?.Invoke(this, eventArgs);
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/PropertyChanged.Fody.Analyzer.Tests/FodyWeavers.xml:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/PropertyChanged.Fody.Analyzer.Tests/FodyWeavers.xsd:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | 'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed.
10 |
11 |
12 |
13 |
14 | A comma-separated list of error codes that can be safely ignored in assembly verification.
15 |
16 |
17 |
18 |
19 | 'false' to turn off automatic generation of the XML Schema file.
20 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/PropertyChanged.Fody.Analyzer.Tests/GlobalUsings.cs:
--------------------------------------------------------------------------------
1 | // Global using directives
2 |
3 | global using System.Text;
4 | global using AnalyzerTesting.CSharp.Extensions;
5 | global using Microsoft.CodeAnalysis;
6 | global using Microsoft.CodeAnalysis.Testing;
7 | global using Microsoft.CodeAnalysis.Testing.Verifiers;
8 | global using Microsoft.CodeAnalysis.Text;
9 | global using PropertyChanged;
--------------------------------------------------------------------------------
/PropertyChanged.Fody.Analyzer.Tests/SourceGeneratorTest.cs:
--------------------------------------------------------------------------------
1 | public class SourceGeneratorTest :
2 | CSharpIncrementalGeneratorSnapshotTest
3 | where TSourceGenerator : IIncrementalGenerator, new()
4 | {
5 | public SourceGeneratorTest(params string[] sources)
6 | {
7 | TestState.Sources.AddRange(sources.Select((source, index) => ($"File#{index}.cs", SourceText.From(source, Encoding.UTF8))));
8 | ReferenceAssemblies = ReferenceAssemblies.NetStandard.NetStandard21;
9 | TestBehaviors = TestBehaviors.SkipGeneratedCodeCheck | TestBehaviors.SkipSuppressionCheck | TestBehaviors.SkipGeneratedSourcesCheck;
10 |
11 | this.AddReferences(typeof(AddINotifyPropertyChangedInterfaceAttribute).Assembly);
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/PropertyChanged.Fody.Analyzer.Tests/Usings.cs:
--------------------------------------------------------------------------------
1 | global using Xunit;
--------------------------------------------------------------------------------
/PropertyChanged.Fody.Analyzer/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Runtime.CompilerServices;
2 |
3 | [assembly: InternalsVisibleTo("PropertyChanged.Fody.Analyzer.Tests")]
4 |
--------------------------------------------------------------------------------
/PropertyChanged.Fody.Analyzer/CodeBuilder.cs:
--------------------------------------------------------------------------------
1 | using System.Text;
2 |
3 | class CodeBuilder
4 | {
5 | readonly StringBuilder _stringBuilder = new();
6 |
7 | int _indent;
8 |
9 | public CodeBuilder Add(string line = "")
10 | {
11 | if (string.IsNullOrEmpty(line))
12 | {
13 | _stringBuilder.AppendLine();
14 | return this;
15 | }
16 |
17 | if (line.StartsWith("}"))
18 | {
19 | --_indent;
20 | }
21 |
22 | _stringBuilder.Append(' ', 4 * _indent).AppendLine(line);
23 |
24 | if (line.StartsWith("{"))
25 | {
26 | ++_indent;
27 | }
28 |
29 | return this;
30 | }
31 |
32 | public override string ToString()
33 | {
34 | return _stringBuilder.ToString();
35 | }
36 | }
37 |
38 |
--------------------------------------------------------------------------------
/PropertyChanged.Fody.Analyzer/PropertyChanged.Fody.Analyzer.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 | netstandard2.0
4 | enable
5 | enable
6 | true
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/PropertyChanged.Fody/AllPropertiesFinder.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Linq;
3 | using Mono.Cecil;
4 |
5 | public partial class ModuleWeaver
6 | {
7 | static void FindAllProperties(List notifyNodes, List list)
8 | {
9 | foreach (var node in notifyNodes)
10 | {
11 | var properties = node.TypeDefinition.Properties.ToList();
12 | properties.AddRange(list);
13 | node.AllProperties = properties;
14 | FindAllProperties(node.Nodes, properties);
15 | }
16 | }
17 |
18 | public void FindAllProperties()
19 | {
20 | FindAllProperties(NotifyNodes, new());
21 | }
22 | }
--------------------------------------------------------------------------------
/PropertyChanged.Fody/CodeGenTypeCleaner.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Linq;
3 |
4 | public partial class ModuleWeaver
5 | {
6 | static void ProcessNotifyNodes(List notifyNodes)
7 | {
8 | foreach (var node in notifyNodes.ToList())
9 | {
10 | var customAttributes = node.TypeDefinition.CustomAttributes;
11 | if (customAttributes.ContainsAttribute("System.Runtime.CompilerServices.CompilerGeneratedAttribute"))
12 | {
13 | notifyNodes.Remove(node);
14 | continue;
15 | }
16 | ProcessNotifyNodes(node.Nodes);
17 | }
18 | }
19 |
20 | public void CleanCodeGenedTypes()
21 | {
22 | ProcessNotifyNodes(NotifyNodes);
23 | }
24 | }
--------------------------------------------------------------------------------
/PropertyChanged.Fody/Config/CheckForEqualityConfig.cs:
--------------------------------------------------------------------------------
1 | using System.Linq;
2 | using System.Xml;
3 |
4 | public partial class ModuleWeaver
5 | {
6 | public bool CheckForEquality = true;
7 |
8 | public void ResolveCheckForEqualityConfig()
9 | {
10 | var value = Config?.Attributes("CheckForEquality")
11 | .Select(a => a.Value)
12 | .SingleOrDefault();
13 | if (value != null)
14 | {
15 | CheckForEquality = XmlConvert.ToBoolean(value.ToLowerInvariant());
16 | }
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/PropertyChanged.Fody/Config/CheckForEqualityUsingBaseEqualsConfig.cs:
--------------------------------------------------------------------------------
1 | using System.Linq;
2 | using System.Xml;
3 |
4 | public partial class ModuleWeaver
5 | {
6 | public bool CheckForEqualityUsingBaseEquals = true;
7 |
8 | public void ResolveCheckForEqualityUsingBaseEqualsConfig()
9 | {
10 | var value = Config?.Attributes("CheckForEqualityUsingBaseEquals")
11 | .Select(a => a.Value)
12 | .SingleOrDefault();
13 | if (value != null)
14 | {
15 | CheckForEqualityUsingBaseEquals = XmlConvert.ToBoolean(value.ToLowerInvariant());
16 | }
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/PropertyChanged.Fody/Config/EnableIsChangedPropertyConfig.cs:
--------------------------------------------------------------------------------
1 | using System.Linq;
2 | using System.Xml;
3 |
4 | public partial class ModuleWeaver
5 | {
6 | public bool EnableIsChangedProperty = true;
7 |
8 | public void ResolveEnableIsChangedPropertyConfig()
9 | {
10 | var value = Config?.Attributes("EnableIsChangedProperty")
11 | .Select(a => a.Value)
12 | .SingleOrDefault();
13 | if (value != null)
14 | {
15 | EnableIsChangedProperty = XmlConvert.ToBoolean(value.ToLowerInvariant());
16 | }
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/PropertyChanged.Fody/Config/InjectOnPropertyNameChangedConfig.cs:
--------------------------------------------------------------------------------
1 | using System.Linq;
2 | using System.Xml;
3 |
4 | public partial class ModuleWeaver
5 | {
6 | public bool InjectOnPropertyNameChanged = true;
7 |
8 | public void ResolveOnPropertyNameChangedConfig()
9 | {
10 | var value = Config?.Attributes("InjectOnPropertyNameChanged")
11 | .Select(a => a.Value)
12 | .SingleOrDefault();
13 | if (value != null)
14 | {
15 | InjectOnPropertyNameChanged = XmlConvert.ToBoolean(value.ToLowerInvariant());
16 | }
17 | }
18 | }
--------------------------------------------------------------------------------
/PropertyChanged.Fody/Config/SuppressOnPropertyNameChangedWarningConfig.cs:
--------------------------------------------------------------------------------
1 | using System.Linq;
2 | using System.Xml;
3 |
4 | public partial class ModuleWeaver
5 | {
6 | public bool SuppressOnPropertyNameChangedWarning;
7 |
8 | public void ResolveSuppressOnPropertyNameChangedWarningConfig()
9 | {
10 | var value = Config?.Attributes("SuppressOnPropertyNameChangedWarning")
11 | .Select(a => a.Value)
12 | .SingleOrDefault();
13 | if (value != null)
14 | {
15 | SuppressOnPropertyNameChangedWarning = XmlConvert.ToBoolean(value.ToLowerInvariant());
16 | }
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/PropertyChanged.Fody/Config/SuppressWarningsConfig.cs:
--------------------------------------------------------------------------------
1 | using System.Linq;
2 | using System.Xml;
3 |
4 | public partial class ModuleWeaver
5 | {
6 | public bool SuppressWarnings;
7 |
8 | public void ResolveSuppressWarningsConfig()
9 | {
10 | var value = Config?.Attributes("SuppressWarnings")
11 | .Select(a => a.Value)
12 | .SingleOrDefault();
13 | if (value != null)
14 | {
15 | SuppressWarnings = XmlConvert.ToBoolean(value.ToLowerInvariant());
16 | }
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/PropertyChanged.Fody/Config/TriggerDependentPropertiesConfig.cs:
--------------------------------------------------------------------------------
1 | using System.Linq;
2 | using System.Xml;
3 |
4 | public partial class ModuleWeaver
5 | {
6 | public bool TriggerDependentProperties = true;
7 |
8 | public void ResolveTriggerDependentPropertiesConfig()
9 | {
10 | var value = Config.Attributes("TriggerDependentProperties")
11 | .Select(_ => _.Value)
12 | .SingleOrDefault();
13 | if (value != null)
14 | {
15 | TriggerDependentProperties = XmlConvert.ToBoolean(value.ToLowerInvariant());
16 | }
17 | }
18 | }
--------------------------------------------------------------------------------
/PropertyChanged.Fody/Config/UseStaticEqualsFromBaseConfig.cs:
--------------------------------------------------------------------------------
1 | using System.Linq;
2 | using System.Xml;
3 |
4 | public partial class ModuleWeaver
5 | {
6 | public bool UseStaticEqualsFromBase;
7 |
8 | public void ResolveUseStaticEqualsFromBaseConfig()
9 | {
10 | var value = Config?.Attributes("UseStaticEqualsFromBase")
11 | .Select(a => a.Value)
12 | .SingleOrDefault();
13 | if (value != null)
14 | {
15 | UseStaticEqualsFromBase = XmlConvert.ToBoolean(value.ToLowerInvariant());
16 | }
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/PropertyChanged.Fody/DoNotNotifyTypeCleaner.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Linq;
3 |
4 | public partial class ModuleWeaver
5 | {
6 | static void Process(List notifyNodes)
7 | {
8 | foreach (var node in notifyNodes.ToList())
9 | {
10 | var containsDoNotNotifyAttribute = node.TypeDefinition.CustomAttributes.ContainsAttribute("PropertyChanged.DoNotNotifyAttribute");
11 | if (containsDoNotNotifyAttribute)
12 | {
13 | notifyNodes.Remove(node);
14 | continue;
15 | }
16 | Process(node.Nodes);
17 | }
18 | }
19 |
20 | public void CleanDoNotNotifyTypes()
21 | {
22 | Process(NotifyNodes);
23 | }
24 | }
--------------------------------------------------------------------------------
/PropertyChanged.Fody/EventArgsCacheInjector.cs:
--------------------------------------------------------------------------------
1 | partial class ModuleWeaver
2 | {
3 | public void InitEventArgsCache()
4 | {
5 | EventArgsCache = new(this);
6 | }
7 |
8 | public void InjectEventArgsCache()
9 | => EventArgsCache.InjectType();
10 |
11 | public EventArgsCache EventArgsCache;
12 | }
13 |
--------------------------------------------------------------------------------
/PropertyChanged.Fody/EventInvokerMethod.cs:
--------------------------------------------------------------------------------
1 | using Mono.Cecil;
2 |
3 | public class EventInvokerMethod
4 | {
5 | public MethodReference MethodReference;
6 | public InvokerTypes InvokerType;
7 | public bool IsVisibleFromChildren;
8 | }
--------------------------------------------------------------------------------
/PropertyChanged.Fody/FilterTypeDataAttributeReader.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Linq;
3 | using Mono.Cecil;
4 |
5 | public partial class ModuleWeaver
6 | {
7 | public List NamespaceFilters { get; private set; }
8 |
9 | public void ProcessFilterTypeAttributes()
10 | {
11 | ReadFilterTypeData(ModuleDefinition);
12 | }
13 |
14 | public void ReadFilterTypeData(ModuleDefinition moduleDefinition)
15 | {
16 | var filterTypeAttribute = moduleDefinition.Assembly.CustomAttributes.GetAttributes("PropertyChanged.FilterTypeAttribute");
17 | if (filterTypeAttribute == null)
18 | {
19 | return;
20 | }
21 | var customAttributeArguments = filterTypeAttribute.Select(_ => _.ConstructorArguments).ToList();
22 | NamespaceFilters = customAttributeArguments.Select(x => (string)x[0].Value).ToList();
23 | }
24 | }
--------------------------------------------------------------------------------
/PropertyChanged.Fody/IlGeneratedByDependencyProcessor.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 |
3 | public partial class ModuleWeaver
4 | {
5 | public void DetectIlGeneratedByDependency()
6 | {
7 | DetectIlGeneratedByDependency(NotifyNodes);
8 | }
9 |
10 | void DetectIlGeneratedByDependency(List notifyNodes)
11 | {
12 | if(!TriggerDependentProperties)
13 | {
14 | return;
15 | }
16 |
17 | foreach (var node in notifyNodes)
18 | {
19 | var ilGeneratedByDependencyReader = new IlGeneratedByDependencyReader(node);
20 | ilGeneratedByDependencyReader.Process();
21 | DetectIlGeneratedByDependency(node.Nodes);
22 | }
23 | }
24 | }
--------------------------------------------------------------------------------
/PropertyChanged.Fody/InstructionListExtensions.cs:
--------------------------------------------------------------------------------
1 | using System.Linq;
2 | using Mono.Cecil.Cil;
3 | using Mono.Collections.Generic;
4 |
5 | public static class InstructionListExtensions
6 | {
7 | public static void Prepend(this Collection collection, params Instruction[] instructions)
8 | {
9 | for (var index = 0; index < instructions.Length; index++)
10 | {
11 | var instruction = instructions[index];
12 | collection.Insert(index, instruction);
13 | }
14 | }
15 |
16 | public static void Append(this Collection collection, params Instruction[] instructions)
17 | {
18 | foreach (var instruction in instructions)
19 | {
20 | collection.Add(instruction);
21 | }
22 | }
23 |
24 | public static int Insert(this Collection collection, int index, params Instruction[] instructions)
25 | {
26 | foreach (var instruction in instructions.Reverse())
27 | {
28 | collection.Insert(index, instruction);
29 | }
30 | return index + instructions.Length;
31 | }
32 | }
--------------------------------------------------------------------------------
/PropertyChanged.Fody/InvokerTypes.cs:
--------------------------------------------------------------------------------
1 | public enum InvokerTypes
2 | {
3 | String,
4 | BeforeAfter,
5 | BeforeAfterGeneric,
6 | PropertyChangedArg,
7 | SenderPropertyChangedArg
8 | }
--------------------------------------------------------------------------------
/PropertyChanged.Fody/MemberMapping.cs:
--------------------------------------------------------------------------------
1 | using Mono.Cecil;
2 |
3 | public class MemberMapping
4 | {
5 | public PropertyDefinition PropertyDefinition;
6 | public FieldDefinition FieldDefinition;
7 | }
--------------------------------------------------------------------------------
/PropertyChanged.Fody/NotifyPropertyData.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using Mono.Cecil;
3 |
4 | public class NotifyPropertyData
5 | {
6 | public List AlsoNotifyFor = new();
7 | }
--------------------------------------------------------------------------------
/PropertyChanged.Fody/OnChangedMethod.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using Mono.Cecil;
3 |
4 | public enum OnChangedTypes
5 | {
6 | None,
7 | NoArg,
8 | BeforeAfter,
9 | BeforeAfterTyped
10 | }
11 |
12 | public class OnChangedMethod
13 | {
14 | public MethodReference MethodReference;
15 | public MethodDefinition MethodDefinition;
16 | public OnChangedTypes OnChangedType;
17 | public string ArgumentTypeFullName;
18 | public bool IsDefaultMethod;
19 | public List Properties = new();
20 | }
21 |
22 |
23 |
--------------------------------------------------------------------------------
/PropertyChanged.Fody/PropertyChanged.Fody.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | netstandard2.0
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/PropertyChanged.Fody/PropertyChangedAddMethodFinder.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.ComponentModel;
3 | using System.Linq;
4 | using Mono.Cecil;
5 |
6 | public static class PropertyChangedAddMethodFinder
7 | {
8 | public static IEnumerable GetPropertyChangedAddMethods(this TypeDefinition targetType)
9 | {
10 | var foundExplicit = false;
11 |
12 | foreach (var method in targetType.Methods.Where(i => i.Overrides.Any(o => o.FullName == "System.Void System.ComponentModel.INotifyPropertyChanged::add_PropertyChanged(System.ComponentModel.PropertyChangedEventHandler)")))
13 | {
14 | foundExplicit = true;
15 | yield return method;
16 | }
17 |
18 | if (foundExplicit)
19 | {
20 | yield break;
21 | }
22 |
23 | foreach (var method in targetType.Events.Where(i => i.Name == nameof(INotifyPropertyChanged.PropertyChanged)))
24 | {
25 | yield return method.AddMethod;
26 | }
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/PropertyChanged.Fody/PropertyData.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using Mono.Cecil;
3 |
4 | public class PropertyData
5 | {
6 | public TypeNode ParentType;
7 | public FieldReference BackingFieldReference;
8 | public List AlsoNotifyFor = new();
9 | public PropertyDefinition PropertyDefinition;
10 | public MethodReference EqualsMethod;
11 | public List AlreadyNotifies = new();
12 | }
13 |
--------------------------------------------------------------------------------
/PropertyChanged.Fody/PropertyDependency.cs:
--------------------------------------------------------------------------------
1 | using Mono.Cecil;
2 |
3 | public class PropertyDependency
4 | {
5 | public PropertyDefinition ShouldAlsoNotifyFor;
6 | public PropertyDefinition WhenPropertyIsSet;
7 | }
--------------------------------------------------------------------------------
/PropertyChanged.Fody/TypeNode.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Linq;
3 | using Mono.Cecil;
4 |
5 | public class TypeNode
6 | {
7 | public TypeDefinition TypeDefinition;
8 | public List Nodes = new();
9 | public List PropertyDependencies = new();
10 | public List Mappings = new();
11 | public EventInvokerMethod EventInvoker;
12 | public MethodReference IsChangedInvoker;
13 | public List PropertyDatas = new();
14 | public List AllProperties;
15 | public ICollection OnChangedMethods;
16 | public IEnumerable DeclaredProperties => AllProperties.Where(prop => prop.DeclaringType == TypeDefinition);
17 | }
18 |
--------------------------------------------------------------------------------
/PropertyChanged.Fody/TypeResolver.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using Mono.Cecil;
4 |
5 | public partial class ModuleWeaver
6 | {
7 | Dictionary definitions = new();
8 |
9 | public TypeDefinition Resolve(TypeReference reference)
10 | {
11 | if (definitions.TryGetValue(reference.FullName, out var definition))
12 | {
13 | return definition;
14 | }
15 | return definitions[reference.FullName] = InnerResolve(reference);
16 | }
17 |
18 | static TypeDefinition InnerResolve(TypeReference reference)
19 | {
20 | TypeDefinition result;
21 |
22 | try
23 | {
24 | result = reference.Resolve();
25 | }
26 | catch (Exception exception)
27 | {
28 | throw new($"Could not resolve '{reference.FullName}'.", exception);
29 | }
30 |
31 | if (result == null)
32 | {
33 | throw new($"Could not resolve '{reference.FullName}'. TypeReference.Resolve returned null.");
34 | }
35 |
36 | return result;
37 | }
38 | }
--------------------------------------------------------------------------------
/PropertyChanged/AddINotifyPropertyChangedInterfaceAttribute.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.ComponentModel;
3 |
4 | namespace PropertyChanged;
5 |
6 | ///
7 | /// Specifies that the class will be marked with .
8 | /// Note that all classes that implement will have property notification
9 | /// injected irrespective of the use of this attribute.
10 | /// Raising an issue about "this attribute does not behave as expected" will result in a RTFM and the issue being closed.
11 | ///
12 | [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, Inherited = false)]
13 | public class AddINotifyPropertyChangedInterfaceAttribute : Attribute;
--------------------------------------------------------------------------------
/PropertyChanged/AlsoNotifyForAttribute.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | // ReSharper disable UnusedParameter.Local
4 | namespace PropertyChanged;
5 |
6 | ///
7 | /// Injects this property to be notified when a dependent property is set.
8 | ///
9 | [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)]
10 | public class AlsoNotifyForAttribute : Attribute
11 | {
12 | ///
13 | /// Initializes a new instance of .
14 | ///
15 | ///A property that will be notified for.
16 | public AlsoNotifyForAttribute(string property)
17 | {
18 | }
19 |
20 | ///
21 | /// Initializes a new instance of .
22 | ///
23 | ///A property that will be notified for.
24 | ///The properties that will be notified for.
25 | public AlsoNotifyForAttribute(string property, params string[] otherProperties)
26 | {
27 | }
28 | }
29 | // ReSharper restore UnusedParameter.Local
--------------------------------------------------------------------------------
/PropertyChanged/DependsOnAttribute.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | // ReSharper disable UnusedParameter.Local
3 |
4 | namespace PropertyChanged;
5 |
6 | ///
7 | /// Injects this property to be notified when a dependent property is set.
8 | ///
9 | [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)]
10 | public class DependsOnAttribute : Attribute
11 | {
12 | ///
13 | /// Initializes a new instance of .
14 | ///
15 | /// A property that the assigned property depends on.
16 | public DependsOnAttribute(string dependency)
17 | {
18 | }
19 |
20 | ///
21 | /// Initializes a new instance of .
22 | ///
23 | /// A property that the assigned property depends on.
24 | /// The properties that the assigned property depends on.
25 | public DependsOnAttribute(string dependency, params string[] otherDependencies)
26 | {
27 | }
28 | }
29 | // ReSharper restore UnusedParameter.Local
--------------------------------------------------------------------------------
/PropertyChanged/DoNotCheckEqualityAttribute.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace PropertyChanged;
4 |
5 | ///
6 | /// Skip equality check before change notification
7 | ///
8 | [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field)]
9 | public class DoNotCheckEqualityAttribute : Attribute;
--------------------------------------------------------------------------------
/PropertyChanged/DoNotNotifyAttribute.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace PropertyChanged;
4 |
5 | ///
6 | /// Exclude a or property from notification.
7 | ///
8 | [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field, Inherited = false)]
9 | public class DoNotNotifyAttribute : Attribute;
--------------------------------------------------------------------------------
/PropertyChanged/DoNotSetChangedAttribute.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace PropertyChanged;
4 |
5 | ///
6 | /// Exclude a or property from IsChanged flagging.
7 | ///
8 | [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)]
9 | public class DoNotSetChangedAttribute : Attribute;
--------------------------------------------------------------------------------
/PropertyChanged/FilterTypeAttribute.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | // ReSharper disable UnusedParameter.Local
3 |
4 | namespace PropertyChanged;
5 |
6 | ///
7 | /// Defines filters on which types to include in the
8 | /// weaving process. These filters are Regex based and
9 | /// are matched against the Type.FullName
10 | ///
11 | [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
12 | public class FilterTypeAttribute : Attribute
13 | {
14 | ///
15 | /// Initializes a new instance of .
16 | ///
17 | /// The filter to apply to the types in this
18 | /// assembly. Matching is done by the Regex.IsMatch method using
19 | /// the Type.FullName as input for the Matching method.
20 | ///
21 | public FilterTypeAttribute(string filter)
22 | {
23 | }
24 | }
25 | // ReSharper restore UnusedParameter.Local
--------------------------------------------------------------------------------
/PropertyChanged/ImplementPropertyChangedAttribute.cs:
--------------------------------------------------------------------------------
1 | #pragma warning disable 1591
2 | using System;
3 |
4 | namespace PropertyChanged;
5 |
6 | [Obsolete(
7 | message: "This configuration option has been deprecated. The use of this attribute was to add INotifyPropertyChanged to a class with its associated event definition. After that all classes that implement INotifyPropertyChanged have their properties weaved, weather they have the ImplementPropertyChangedAttribute or not. This attribute was often incorrectly interpreted as an opt in approach to having properties weaved, which was never the intent nor how it ever operated. This attribute has been replaced by AddINotifyPropertyChangedInterfaceAttribute.",
8 | error: true)]
9 | public class ImplementPropertyChangedAttribute : Attribute;
--------------------------------------------------------------------------------
/PropertyChanged/OnChangedMethodAttribute.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | // ReSharper disable UnusedParameter.Local
4 |
5 | namespace PropertyChanged;
6 |
7 | ///
8 | /// Specifies a method to call when the property value changes.
9 | /// Adding this attribute suppresses the default behavior of calling the On<PropertyName>Changed method if it exists.
10 | ///
11 | [AttributeUsage(AttributeTargets.Property, AllowMultiple = true)]
12 | public sealed class OnChangedMethodAttribute : Attribute
13 | {
14 | ///
15 | /// Initializes a new instance of .
16 | ///
17 | ///
18 | /// The name of a method to call when the property value changes.
19 | /// When null or empty, does not call any method - this can be used to suppress the default behavior of calling the On<PropertyName>Changed method.
20 | ///
21 | public OnChangedMethodAttribute(string methodName)
22 | {
23 | }
24 | }
--------------------------------------------------------------------------------
/PropertyChanged/SuppressPropertyChangedWarningsAttribute.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace PropertyChanged;
4 |
5 | ///
6 | /// Suppresses warnings emitted by PropertyChanged.Fody
7 | ///
8 | [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Method)]
9 | public sealed class SuppressPropertyChangedWarningsAttribute : Attribute;
--------------------------------------------------------------------------------
/PropertyChanged/Weaver.props:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/PropertyChanged/key.snk:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Fody/PropertyChanged/a7de98072c1d4e1737cc1b304277ed14c7da09bb/PropertyChanged/key.snk
--------------------------------------------------------------------------------
/SmokeTest/Classes.cs:
--------------------------------------------------------------------------------
1 | namespace SmokeTest;
2 |
3 | using System.ComponentModel;
4 |
5 | using PropertyChanged;
6 |
7 | #pragma warning disable CS0067
8 |
9 | public class Class1 :
10 | INotifyPropertyChanged
11 | {
12 | public int Property1 { get; set; }
13 |
14 | public event PropertyChangedEventHandler PropertyChanged;
15 | }
16 |
17 | [AddINotifyPropertyChangedInterface]
18 | public class Class2
19 | {
20 | public int Property1 { get; set; }
21 | }
22 |
23 | public class Class3 :
24 | INotifyPropertyChanged
25 | {
26 | [AlsoNotifyFor(nameof(Property3))]
27 | public int Property1 { get; set; }
28 |
29 | [DependsOn(nameof(Property1))]
30 | public int Property2 { get; set; }
31 |
32 | public int Property3 { get; set; }
33 |
34 | public event PropertyChangedEventHandler PropertyChanged;
35 | }
36 |
37 | public class Class4 :
38 | INotifyPropertyChanged
39 | {
40 | public bool HasChanged { get; set; }
41 |
42 | public int Property1 { get; set; }
43 |
44 | public event PropertyChangedEventHandler PropertyChanged;
45 | }
--------------------------------------------------------------------------------
/SmokeTest/CombinedChangingAndChangedWeaverTests.ValueTypeProperty.Debug.verified.il:
--------------------------------------------------------------------------------
1 | .method public hidebysig specialname
2 | instance void set_Property2 (
3 | int32 'value'
4 | ) cil managed
5 | {
6 | .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = (
7 | 01 00 00 00
8 | )
9 | // Header size: 12
10 | // Code size: 45 (0x2d)
11 | .maxstack 2
12 |
13 | IL_0000: ldarg.0
14 | IL_0001: ldfld int32 SmokeTest.Testee::'k__BackingField'
15 | IL_0006: ldarg.1
16 | IL_0007: ceq
17 | IL_0009: brfalse.s IL_000d
18 |
19 | IL_000b: br.s IL_002b
20 |
21 | IL_000d: nop
22 | IL_000e: ldarg.0
23 | IL_000f: ldstr "Property2"
24 | IL_0014: callvirt instance void SmokeTest.Testee::OnPropertyChanging(string)
25 | IL_0019: ldarg.0
26 | IL_001a: ldarg.1
27 | IL_001b: stfld int32 SmokeTest.Testee::'k__BackingField'
28 | IL_0020: ldarg.0
29 | IL_0021: ldsfld class [System]System.ComponentModel.PropertyChangedEventArgs 'SmokeTest.<>PropertyChangedEventArgs'::Property2
30 | IL_0026: callvirt instance void SmokeTest.Testee::'<>OnPropertyChanged'(class [System]System.ComponentModel.PropertyChangedEventArgs)
31 |
32 | IL_002b: nop
33 | IL_002c: ret
34 | } // end of method Testee::set_Property2
35 |
--------------------------------------------------------------------------------
/SmokeTest/CombinedChangingAndChangedWeaverTests.ValueTypeProperty.Release.verified.il:
--------------------------------------------------------------------------------
1 | .method public hidebysig specialname
2 | instance void set_Property2 (
3 | int32 'value'
4 | ) cil managed
5 | {
6 | .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = (
7 | 01 00 00 00
8 | )
9 | // Header size: 12
10 | // Code size: 45 (0x2d)
11 | .maxstack 2
12 |
13 | IL_0000: ldarg.0
14 | IL_0001: ldfld int32 SmokeTest.Testee::'k__BackingField'
15 | IL_0006: ldarg.1
16 | IL_0007: ceq
17 | IL_0009: brfalse.s IL_000d
18 |
19 | IL_000b: br.s IL_002b
20 |
21 | IL_000d: nop
22 | IL_000e: ldarg.0
23 | IL_000f: ldstr "Property2"
24 | IL_0014: callvirt instance void SmokeTest.Testee::OnPropertyChanging(string)
25 | IL_0019: ldarg.0
26 | IL_001a: ldarg.1
27 | IL_001b: stfld int32 SmokeTest.Testee::'k__BackingField'
28 | IL_0020: ldarg.0
29 | IL_0021: ldsfld class [System]System.ComponentModel.PropertyChangedEventArgs 'SmokeTest.<>PropertyChangedEventArgs'::Property2
30 | IL_0026: callvirt instance void SmokeTest.Testee::'<>OnPropertyChanged'(class [System]System.ComponentModel.PropertyChangedEventArgs)
31 |
32 | IL_002b: nop
33 | IL_002c: ret
34 | } // end of method Testee::set_Property2
35 |
--------------------------------------------------------------------------------
/SmokeTest/FodyWeavers.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/TestAssemblies/AssemblyExplicitPropertyChanged/AssemblyExplicitPropertyChanged.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | net48;net6.0
5 | CS0067
6 | true
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/TestAssemblies/AssemblyExplicitPropertyChanged/ClassExplicitPropertyChanged.cs:
--------------------------------------------------------------------------------
1 | using System.ComponentModel;
2 | #pragma warning disable 649
3 |
4 | public class ClassExplicitPropertyChanged :
5 | INotifyPropertyChanged
6 | {
7 | public event PropertyChangedEventHandler PropertyChanged
8 | {
9 | add { }
10 | remove { }
11 | }
12 | }
--------------------------------------------------------------------------------
/TestAssemblies/AssemblyFSharp/AssemblyFSharp.fsproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | netstandard2.0
5 | true
6 | 1.0.0
7 | 7.0
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/TestAssemblies/AssemblyFSharp/ClassWithNoOnPropertyChanged.fs:
--------------------------------------------------------------------------------
1 | namespace Namespace
2 |
3 | open System.ComponentModel
4 |
5 | type ClassWithNoOnPropertyChanged() =
6 | let mutable propval =""
7 |
8 | let event = new Event<_,_>()
9 | interface INotifyPropertyChanged with
10 | []
11 | member x.PropertyChanged = event.Publish
12 |
13 | member this.Property1
14 | with get() = propval
15 | and set(v) = propval <- v
--------------------------------------------------------------------------------
/TestAssemblies/AssemblyFSharp/ClassWithProperties.fs:
--------------------------------------------------------------------------------
1 | namespace Namespace
2 |
3 | open System.ComponentModel
4 |
5 | type ClassWithProperties() =
6 | let mutable propval =""
7 |
8 | let event = new Event<_,_>()
9 | interface INotifyPropertyChanged with
10 | []
11 | member x.PropertyChanged = event.Publish
12 |
13 | member x.OnPropertyChanged(name)=
14 | event.Trigger(x, new PropertyChangedEventArgs(name))
15 |
16 | member this.Property1
17 | with get() = propval
18 | and set(v) = propval <- v
--------------------------------------------------------------------------------
/TestAssemblies/AssemblyInheritingBadNamedInvoker/AssemblyInheritingBadNamedInvoker.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | net48;net6.0
5 | true
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/TestAssemblies/AssemblyInheritingBadNamedInvoker/ChildClass.cs:
--------------------------------------------------------------------------------
1 |
2 | public class ChildClass : BaseClass
3 | {
4 | public string Property1 { get; set; }
5 | }
--------------------------------------------------------------------------------
/TestAssemblies/AssemblyToProcess/AbstractProperty/ClassWithAbstractProperty.cs:
--------------------------------------------------------------------------------
1 | using System.ComponentModel;
2 |
3 | public abstract class ClassWithAbstractProperty :
4 | INotifyPropertyChanged
5 | {
6 | public event PropertyChangedEventHandler PropertyChanged;
7 |
8 | public abstract string Property1 { get; set; }
9 | }
--------------------------------------------------------------------------------
/TestAssemblies/AssemblyToProcess/AbstractProperty/ClassWithPropertyImp.cs:
--------------------------------------------------------------------------------
1 | public class ClassWithPropertyImp : ClassWithAbstractProperty
2 | {
3 | public override string Property1 { get; set; }
4 | }
--------------------------------------------------------------------------------
/TestAssemblies/AssemblyToProcess/AssemblyToProcess.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | net48;net6.0
5 | 0067;0649
6 | true
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/TestAssemblies/AssemblyToProcess/ClassAlreadyHasNotification.cs:
--------------------------------------------------------------------------------
1 | using System.ComponentModel;
2 |
3 | public class ClassAlreadyHasNotification :
4 | INotifyPropertyChanged
5 | {
6 | string property1;
7 |
8 | public string Property1
9 | {
10 | get => property1;
11 | set
12 | {
13 | property1 = value;
14 | OnPropertyChanged("Property1");
15 | OnPropertyChanged("Property2");
16 | }
17 | }
18 |
19 | public virtual void OnPropertyChanged(string propertyName)
20 | {
21 | PropertyChanged?.Invoke(this, new(propertyName));
22 | }
23 |
24 | public event PropertyChangedEventHandler PropertyChanged;
25 | }
--------------------------------------------------------------------------------
/TestAssemblies/AssemblyToProcess/ClassAlreadyHasSingleNotification.cs:
--------------------------------------------------------------------------------
1 | using System.ComponentModel;
2 |
3 | public class ClassAlreadyHasSingleNotification :
4 | INotifyPropertyChanged
5 | {
6 | string property1;
7 |
8 | public string Property1
9 | {
10 | get => property1;
11 | set
12 | {
13 | property1 = value;
14 | OnPropertyChanged("Property1");
15 | }
16 | }
17 | public string Property2 => Property1;
18 |
19 | public virtual void OnPropertyChanged(string propertyName)
20 | {
21 | PropertyChanged?.Invoke(this, new(propertyName));
22 | }
23 |
24 | public event PropertyChangedEventHandler PropertyChanged;
25 | }
--------------------------------------------------------------------------------
/TestAssemblies/AssemblyToProcess/ClassAlreadyHasSingleNotificationDiffParamLocation.cs:
--------------------------------------------------------------------------------
1 | using System.ComponentModel;
2 |
3 | public class ClassAlreadyHasSingleNotificationDiffParamLocation :
4 | INotifyPropertyChanged
5 | {
6 | string property1;
7 |
8 | public string Property1
9 | {
10 | get => property1;
11 | set
12 | {
13 | property1 = value;
14 | OnPropertyChanged(7, "Property1");
15 | }
16 | }
17 | public string Property2 => Property1;
18 |
19 | public virtual void OnPropertyChanged(int fake, string propertyName)
20 | {
21 | PropertyChanged?.Invoke(this, new(propertyName));
22 | }
23 |
24 | public event PropertyChangedEventHandler PropertyChanged;
25 | }
--------------------------------------------------------------------------------
/TestAssemblies/AssemblyToProcess/ClassAlreadyHasSingleNotificationDiffSignature.cs:
--------------------------------------------------------------------------------
1 | using System.ComponentModel;
2 |
3 | public class ClassAlreadyHasSingleNotificationDiffSignature :
4 | INotifyPropertyChanged
5 | {
6 | string property1;
7 |
8 | public string Property1
9 | {
10 | get => property1;
11 | set
12 | {
13 | property1 = value;
14 | OnPropertyChanged("Property1", 5);
15 | }
16 | }
17 |
18 | public virtual void OnPropertyChanged(string propertyName, int fake)
19 | {
20 | PropertyChanged?.Invoke(this, new(propertyName));
21 | }
22 |
23 | public event PropertyChangedEventHandler PropertyChanged;
24 | }
--------------------------------------------------------------------------------
/TestAssemblies/AssemblyToProcess/ClassAlsoNotifyFor.cs:
--------------------------------------------------------------------------------
1 | using System.ComponentModel;
2 | using PropertyChanged;
3 |
4 | public class ClassAlsoNotifyFor :
5 | INotifyPropertyChanged
6 | {
7 | [AlsoNotifyFor("Property2")]
8 | public string Property1 { get; set; }
9 | public string Property2 { get; set; }
10 | public event PropertyChangedEventHandler PropertyChanged;
11 | }
--------------------------------------------------------------------------------
/TestAssemblies/AssemblyToProcess/ClassAlsoNotifyForMultiple.cs:
--------------------------------------------------------------------------------
1 | using System.ComponentModel;
2 | using PropertyChanged;
3 |
4 | public class ClassAlsoNotifyForMultiple :
5 | INotifyPropertyChanged
6 | {
7 | [AlsoNotifyFor("Property2", "Property3")]
8 | public string Property1 { get; set; }
9 |
10 | public string Property2 { get; set; }
11 | public string Property3 { get; set; }
12 | public event PropertyChangedEventHandler PropertyChanged;
13 | }
--------------------------------------------------------------------------------
/TestAssemblies/AssemblyToProcess/ClassCircularProperties.cs:
--------------------------------------------------------------------------------
1 | using System.ComponentModel;
2 | using PropertyChanged;
3 |
4 | public class ClassCircularProperties :
5 | INotifyPropertyChanged
6 | {
7 | public event PropertyChangedEventHandler PropertyChanged;
8 |
9 | [DependsOn("Self")]
10 | public string Self { get; set; }
11 |
12 | [DependsOn("PropertyA2")]
13 | public string PropertyA1 { get; set; }
14 |
15 | [DependsOn("PropertyA1")]
16 | public string PropertyA2 { get; set; }
17 |
18 | [AlsoNotifyFor("PropertyB2")]
19 | public string PropertyB1 { get; set; }
20 |
21 | [AlsoNotifyFor("PropertyB1")]
22 | public string PropertyB2 { get; set; }
23 | }
--------------------------------------------------------------------------------
/TestAssemblies/AssemblyToProcess/ClassDependsOn.cs:
--------------------------------------------------------------------------------
1 | using System.ComponentModel;
2 | using PropertyChanged;
3 |
4 | public class ClassDependsOn :
5 | INotifyPropertyChanged
6 | {
7 | public string Property1 { get; set; }
8 |
9 | [DependsOn("Property1")]
10 | public string Property2 { get; set; }
11 |
12 | public event PropertyChangedEventHandler PropertyChanged;
13 | }
--------------------------------------------------------------------------------
/TestAssemblies/AssemblyToProcess/ClassDoNotCheckEquality.cs:
--------------------------------------------------------------------------------
1 | using System.ComponentModel;
2 |
3 | public class ClassDoNotCheckEquality :
4 | INotifyPropertyChanged
5 | {
6 | public int TimesProperty1Changed;
7 | public int TimesProperty2Changed;
8 |
9 | public string Property1 { get; set; }
10 |
11 | [PropertyChanged.DoNotCheckEquality]
12 | public string Property2 { get; set; }
13 |
14 | public void OnProperty1Changed()
15 | {
16 | TimesProperty1Changed += 1;
17 | }
18 |
19 | public void OnProperty2Changed()
20 | {
21 | TimesProperty2Changed += 1;
22 | }
23 |
24 | public event PropertyChangedEventHandler PropertyChanged;
25 | }
--------------------------------------------------------------------------------
/TestAssemblies/AssemblyToProcess/ClassDoNotCheckEqualityWholeClass.cs:
--------------------------------------------------------------------------------
1 | using System.ComponentModel;
2 |
3 | [PropertyChanged.DoNotCheckEquality]
4 | public class ClassDoNotCheckEqualityWholeClass :
5 | INotifyPropertyChanged
6 | {
7 | public int TimesProperty1Changed;
8 | public int TimesProperty2Changed;
9 |
10 | public string Property1 { get; set; }
11 |
12 | public string Property2 { get; set; }
13 |
14 | public void OnProperty1Changed()
15 | {
16 | TimesProperty1Changed += 1;
17 | }
18 |
19 | public void OnProperty2Changed()
20 | {
21 | TimesProperty2Changed += 1;
22 | }
23 |
24 | public event PropertyChangedEventHandler PropertyChanged;
25 | }
26 |
27 | public class ClassDoNotCheckEqualityWholeClassInherited :
28 | ClassDoNotCheckEqualityWholeClass;
--------------------------------------------------------------------------------
/TestAssemblies/AssemblyToProcess/ClassEquality.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.ComponentModel;
3 |
4 | public class ClassEquality :
5 | INotifyPropertyChanged
6 | {
7 | DateTimeOffset? mixDateTimeOffset;
8 | public string StringProperty { get; set; }
9 | public int IntProperty { get; set; }
10 | public int? NullableIntProperty { get; set; }
11 | public bool BoolProperty { get; set; }
12 | public bool? NullableBoolProperty { get; set; }
13 | public DateTime? NullableDateTime { get; set; }
14 | public DateTime DateTime { get; set; }
15 | public DateTimeOffset? NullableDateTimeOffset { get; set; }
16 | public DateTimeOffset DateTimeOffset { get; set; }
17 |
18 | public DateTimeOffset MixDateTimeOffset
19 | {
20 | get => mixDateTimeOffset.GetValueOrDefault();
21 | set => mixDateTimeOffset = value;
22 | }
23 |
24 | public object ObjectProperty { get; set; }
25 | public short ShortProperty { get; set; }
26 | public ushort UShortProperty { get; set; }
27 | public byte ByteProperty { get; set; }
28 | public sbyte SByteProperty { get; set; }
29 | public char CharProperty { get; set; }
30 | public event PropertyChangedEventHandler PropertyChanged;
31 | }
--------------------------------------------------------------------------------
/TestAssemblies/AssemblyToProcess/ClassEqualityWithDouble.cs:
--------------------------------------------------------------------------------
1 | using System.ComponentModel;
2 |
3 | public class ClassEqualityWithDouble :
4 | INotifyPropertyChanged
5 | {
6 | public double Property1 { get; set; }
7 |
8 | public event PropertyChangedEventHandler PropertyChanged;
9 | }
--------------------------------------------------------------------------------
/TestAssemblies/AssemblyToProcess/ClassEqualityWithGenericStructOverload.cs:
--------------------------------------------------------------------------------
1 | using System.ComponentModel;
2 |
3 | public class ClassEqualityWithGenericStructOverload :
4 | INotifyPropertyChanged
5 | {
6 | public SimpleStruct Property1 { get; set; }
7 |
8 | public event PropertyChangedEventHandler PropertyChanged;
9 |
10 | #pragma warning disable 660,661
11 | public struct SimpleStruct
12 | #pragma warning restore 660,661
13 | {
14 |
15 | public int X;
16 |
17 | public static bool operator ==(SimpleStruct left, SimpleStruct right)
18 | {
19 | return left.X == right.X;
20 | }
21 |
22 | public static bool operator !=(SimpleStruct left, SimpleStruct right)
23 | {
24 | return !(left == right);
25 | }
26 | }
27 | }
--------------------------------------------------------------------------------
/TestAssemblies/AssemblyToProcess/ClassEqualityWithStruct.cs:
--------------------------------------------------------------------------------
1 | using System.ComponentModel;
2 |
3 | public class ClassEqualityWithStruct :
4 | INotifyPropertyChanged
5 | {
6 | public SimpleStruct Property1 { get; set; }
7 |
8 | public event PropertyChangedEventHandler PropertyChanged;
9 |
10 | public struct SimpleStruct
11 | {
12 | public int X;
13 |
14 | public SimpleStruct(int x)
15 | {
16 | X = x;
17 | }
18 | }
19 | }
--------------------------------------------------------------------------------
/TestAssemblies/AssemblyToProcess/ClassEqualityWithStructOverload.cs:
--------------------------------------------------------------------------------
1 | using System.ComponentModel;
2 |
3 | public class ClassEqualityWithStructOverload :
4 | INotifyPropertyChanged
5 | {
6 | public SimpleStruct Property1 { get; set; }
7 |
8 | public event PropertyChangedEventHandler PropertyChanged;
9 |
10 | #pragma warning disable 660,661
11 | public struct SimpleStruct
12 | #pragma warning restore 660,661
13 | {
14 |
15 | public int X;
16 |
17 | public static bool operator ==(SimpleStruct left, SimpleStruct right)
18 | {
19 | return left.X == right.X;
20 | }
21 |
22 | public static bool operator !=(SimpleStruct left, SimpleStruct right)
23 | {
24 | return !(left == right);
25 | }
26 | }
27 | }
--------------------------------------------------------------------------------
/TestAssemblies/AssemblyToProcess/ClassMissingSetGet.cs:
--------------------------------------------------------------------------------
1 | using System.ComponentModel;
2 | // ReSharper disable ConvertToAutoPropertyWithPrivateSetter
3 |
4 | public class ClassMissingSetGet :
5 | INotifyPropertyChanged
6 | {
7 | string property;
8 |
9 | public string PropertyNoSet => property;
10 |
11 |
12 | public string PropertyNoGet
13 | {
14 | set => property = value;
15 | }
16 |
17 | public event PropertyChangedEventHandler PropertyChanged;
18 | }
--------------------------------------------------------------------------------
/TestAssemblies/AssemblyToProcess/ClassNoBackingNoEqualityField.cs:
--------------------------------------------------------------------------------
1 | using System.ComponentModel;
2 | // ReSharper disable ValueParameterNotUsed
3 |
4 | public class ClassNoBackingNoEqualityField :
5 | INotifyPropertyChanged
6 | {
7 | public string StringProperty
8 | {
9 | get => "Foo";
10 | set { }
11 | }
12 |
13 | public event PropertyChangedEventHandler PropertyChanged;
14 | }
--------------------------------------------------------------------------------
/TestAssemblies/AssemblyToProcess/ClassNoBackingWithEqualityField.cs:
--------------------------------------------------------------------------------
1 | using System.ComponentModel;
2 | // ReSharper disable ValueParameterNotUsed
3 |
4 | public class ClassNoBackingWithEqualityField :
5 | INotifyPropertyChanged
6 | {
7 | public string StringProperty
8 | {
9 | get => "Foo";
10 | set { }
11 | }
12 |
13 | public event PropertyChangedEventHandler PropertyChanged;
14 | }
--------------------------------------------------------------------------------
/TestAssemblies/AssemblyToProcess/ClassSetterEndsOnThrowInRelease.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.ComponentModel;
3 |
4 | public class ClassSetterEndsOnThrowInRelease :
5 | INotifyPropertyChanged
6 | {
7 | public event PropertyChangedEventHandler PropertyChanged;
8 |
9 | string item;
10 |
11 | public string Item
12 | {
13 | get => item;
14 | set
15 | {
16 | if (value == "Foo")
17 | {
18 | item = "Bar";
19 | }
20 | else
21 | {
22 | throw new ArgumentOutOfRangeException(nameof(value));
23 | }
24 | }
25 | }
26 | }
--------------------------------------------------------------------------------
/TestAssemblies/AssemblyToProcess/ClassStaticProperties.cs:
--------------------------------------------------------------------------------
1 | using System.ComponentModel;
2 |
3 | public class ClassStaticProperties :
4 | INotifyPropertyChanged
5 | {
6 | public event PropertyChangedEventHandler PropertyChanged;
7 | public static string Property { get; set; }
8 | }
--------------------------------------------------------------------------------
/TestAssemblies/AssemblyToProcess/ClassThatIsNotSealed.cs:
--------------------------------------------------------------------------------
1 | using System.ComponentModel;
2 |
3 | public class ClassThatIsNotSealed :
4 | INotifyPropertyChanged
5 | {
6 | public string Property1 { get; set; }
7 | public event PropertyChangedEventHandler PropertyChanged;
8 | }
--------------------------------------------------------------------------------
/TestAssemblies/AssemblyToProcess/ClassThatIsSealed.cs:
--------------------------------------------------------------------------------
1 | using System.ComponentModel;
2 |
3 | public sealed class ClassThatIsSealed :
4 | INotifyPropertyChanged
5 | {
6 | public string Property1 { get; set; }
7 | public event PropertyChangedEventHandler PropertyChanged;
8 | }
--------------------------------------------------------------------------------
/TestAssemblies/AssemblyToProcess/ClassWithAlsoNotifyFor.cs:
--------------------------------------------------------------------------------
1 | using System.ComponentModel;
2 | using PropertyChanged;
3 |
4 | public class ClassWithAlsoNotifyFor :
5 | INotifyPropertyChanged
6 | {
7 | [AlsoNotifyFor("Property2")]
8 | public string Property1 { get; set; }
9 | public string Property2 { get; set; }
10 | public event PropertyChangedEventHandler PropertyChanged;
11 | }
--------------------------------------------------------------------------------
/TestAssemblies/AssemblyToProcess/ClassWithBeforeAfterAndSimpleImplementation.cs:
--------------------------------------------------------------------------------
1 | using System.ComponentModel;
2 | using PropertyChanged;
3 |
4 | public class ClassWithBeforeAfterAndSimpleImplementation :
5 | INotifyPropertyChanged
6 | {
7 | public string Property1 { get; set; }
8 |
9 | [DependsOn("Property1")]
10 | public string Property2 { get; set; }
11 |
12 | public event PropertyChangedEventHandler PropertyChanged;
13 |
14 | public void OnPropertyChanged(string propertyName)
15 | {
16 | }
17 |
18 | public void OnPropertyChanged(string propertyName, object before, object after)
19 | {
20 | PropertyChanged?.Invoke(this, new(propertyName));
21 | }
22 | }
--------------------------------------------------------------------------------
/TestAssemblies/AssemblyToProcess/ClassWithBeforeAfterImplementation.cs:
--------------------------------------------------------------------------------
1 | using System.ComponentModel;
2 | using PropertyChanged;
3 |
4 | public class ClassWithBeforeAfterImplementation :
5 | INotifyPropertyChanged
6 | {
7 | public string Property1 { get; set; }
8 |
9 | [DependsOn("Property1")]
10 | public string Property2 { get; set; }
11 |
12 | public event PropertyChangedEventHandler PropertyChanged;
13 |
14 | public void OnPropertyChanged(string propertyName, object before, object after)
15 | {
16 | ValidateIsString(after);
17 | ValidateIsString(before);
18 |
19 | PropertyChanged?.Invoke(this, new(propertyName));
20 | }
21 |
22 | static void ValidateIsString(object value)
23 | {
24 | if (value != null)
25 | {
26 | var name = value.GetType().Name;
27 | if (name != "String")
28 | {
29 | throw new($"Value should be string but is '{name}'.");
30 | }
31 | }
32 | }
33 | }
--------------------------------------------------------------------------------
/TestAssemblies/AssemblyToProcess/ClassWithBeforeAfterImplementationMissingSetGet.cs:
--------------------------------------------------------------------------------
1 | using System.ComponentModel;
2 | // ReSharper disable ConvertToAutoPropertyWithPrivateSetter
3 |
4 | public class ClassWithBeforeAfterImplementationMissingSetGet :
5 | INotifyPropertyChanged
6 | {
7 | string property;
8 |
9 | public string PropertyNoSet => property;
10 |
11 |
12 | public string PropertyNoGet
13 | {
14 | set => property = value;
15 | }
16 |
17 | public event PropertyChangedEventHandler PropertyChanged;
18 |
19 | public void OnPropertyChanged(string propertyName, object before, object after)
20 | {
21 | PropertyChanged?.Invoke(this, new(propertyName));
22 | }
23 | }
--------------------------------------------------------------------------------
/TestAssemblies/AssemblyToProcess/ClassWithBeforeAfterValueCheckImplementation.cs:
--------------------------------------------------------------------------------
1 | using System.ComponentModel;
2 | using PropertyChanged;
3 |
4 | public class ClassWithBeforeAfterValueCheckImplementation :
5 | INotifyPropertyChanged
6 | {
7 | public string Property1 { get; set; }
8 |
9 | [DoNotNotify]
10 | public string BeforeValue1 { get; set; }
11 |
12 | [DependsOn("Property1")]
13 | public string Property2 => Property1 + "2";
14 |
15 | [DoNotNotify]
16 | public string BeforeValue2 { get; set; }
17 |
18 | public event PropertyChangedEventHandler PropertyChanged;
19 |
20 | public void OnPropertyChanged(string propertyName, object before, object after)
21 | {
22 | if (propertyName.Equals("Property1"))
23 | {
24 | BeforeValue1 = (string)before;
25 | }
26 |
27 | if (propertyName.Equals("Property2"))
28 | {
29 | BeforeValue2 = (string)before;
30 | }
31 |
32 | PropertyChanged?.Invoke(this, new(propertyName));
33 | }
34 | }
--------------------------------------------------------------------------------
/TestAssemblies/AssemblyToProcess/ClassWithBoolPropUsingStringProp.cs:
--------------------------------------------------------------------------------
1 | using System.ComponentModel;
2 |
3 | public class ClassWithBoolPropUsingStringProp: INotifyPropertyChanged
4 | {
5 | public bool StringCompareProperty => StringProperty == "magicString";
6 |
7 | public bool BoolProperty { get; set; }
8 |
9 | string stringProperty;
10 | public string StringProperty
{
11 | get => stringProperty;
set
12 | {
13 | stringProperty = value;
14 | if (StringCompareProperty)
15 | {
16 | BoolProperty = true;
17 | }
18 | }
19 | }
20 |
21 | public event PropertyChangedEventHandler PropertyChanged;
22 | }
--------------------------------------------------------------------------------
/TestAssemblies/AssemblyToProcess/ClassWithBranchingReturn1.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.ComponentModel;
3 | #pragma warning disable 649
4 | // ReSharper disable RedundantJumpStatement
5 |
6 | public class ClassWithBranchingReturn1 :
7 | INotifyPropertyChanged
8 | {
9 | string property1;
10 | bool isInSomeMode;
11 |
12 | public string Property1
13 | {
14 | get => property1;
15 | set
16 | {
17 | property1 = value;
18 | if (isInSomeMode)
19 | {
20 | Console.WriteLine("code here so 'if' does not get optimized away in release mode");
21 | return;
22 | }
23 | }
24 | }
25 |
26 | public event PropertyChangedEventHandler PropertyChanged;
27 | }
--------------------------------------------------------------------------------
/TestAssemblies/AssemblyToProcess/ClassWithBranchingReturn2.cs:
--------------------------------------------------------------------------------
1 | using System.ComponentModel;
2 |
3 | public class ClassWithBranchingReturn2 :
4 | INotifyPropertyChanged
5 | {
6 | string property1;
7 | public bool HasValue;
8 |
9 | public string Property1
10 | {
11 | get => property1;
12 | set
13 | {
14 | if (HasValue)
15 | {
16 | property1 = value;
17 | }
18 | else
19 | {
20 | property1 = value;
21 | }
22 | }
23 | }
24 |
25 | public event PropertyChangedEventHandler PropertyChanged;
26 | }
--------------------------------------------------------------------------------
/TestAssemblies/AssemblyToProcess/ClassWithBranchingReturnAndBeforeAfter.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.ComponentModel;
3 | #pragma warning disable 649
4 |
5 | public class ClassWithBranchingReturnAndBeforeAfter :
6 | INotifyPropertyChanged
7 | {
8 | string property1;
9 | bool isInSomeMode;
10 | public event PropertyChangedEventHandler PropertyChanged;
11 |
12 | public string Property1
13 | {
14 | get => property1;
15 | set
16 | {
17 | property1 = value;
18 | if (isInSomeMode)
19 | {
20 | Console.WriteLine("code here so 'if' does not get optimized away in release mode");
21 | // ReSharper disable RedundantJumpStatement
22 | return;
23 | // ReSharper restore RedundantJumpStatement
24 | }
25 | }
26 | }
27 |
28 | public void OnPropertyChanged(string propertyName, object before, object after)
29 | {
30 | PropertyChanged?.Invoke(this, new(propertyName));
31 | }
32 | }
--------------------------------------------------------------------------------
/TestAssemblies/AssemblyToProcess/ClassWithBranchingReturnAndNoField.cs:
--------------------------------------------------------------------------------
1 | using System.ComponentModel;
2 | // ReSharper disable ValueParameterNotUsed
3 | // ReSharper disable NotAccessedField.Local
4 |
5 | public class ClassWithBranchingReturnAndNoField :
6 | INotifyPropertyChanged
7 | {
8 | int x;
9 | public bool HasValue;
10 |
11 | public string Property1
12 | {
13 | get => null;
14 | set
15 | {
16 | if (HasValue)
17 | {
18 | x++;
19 | }
20 | else
21 | {
22 | x++;
23 | }
24 | }
25 | }
26 |
27 | public event PropertyChangedEventHandler PropertyChanged;
28 | }
--------------------------------------------------------------------------------
/TestAssemblies/AssemblyToProcess/ClassWithCustomPropertyChanged.cs:
--------------------------------------------------------------------------------
1 | using System.ComponentModel;
2 |
3 | public class ClassWithCustomPropertyChanged :
4 | INotifyPropertyChanged
5 | {
6 | // ReSharper disable NotAccessedField.Local
7 | PropertyChangedEventHandler propertyChanged;
8 | // ReSharper restore NotAccessedField.Local
9 |
10 | public event PropertyChangedEventHandler PropertyChanged
11 | {
12 | add => propertyChanged += value;
13 | remove => propertyChanged -= value;
14 | }
15 |
16 | public string Property1 { get; set; }
17 | }
--------------------------------------------------------------------------------
/TestAssemblies/AssemblyToProcess/ClassWithDependencyAfterSet.cs:
--------------------------------------------------------------------------------
1 | using System.ComponentModel;
2 |
3 | public class ClassWithDependencyAfterSet :
4 | INotifyPropertyChanged
5 | {
6 | public event PropertyChangedEventHandler PropertyChanged;
7 |
8 | string property2;
9 |
10 | // ReSharper disable ConvertToAutoProperty
11 | public string Property2
12 | {
13 | get => property2;
14 | set => property2 = value;
15 | }
16 | // ReSharper restore ConvertToAutoProperty
17 |
18 | string property1;
19 |
20 | public string Property1
21 | {
22 | get => property1;
23 | set
24 | {
25 | property1 = value;
26 | Property2 = value;
27 | }
28 | }
29 | }
--------------------------------------------------------------------------------
/TestAssemblies/AssemblyToProcess/ClassWithDependsOn.cs:
--------------------------------------------------------------------------------
1 | using System.ComponentModel;
2 | using PropertyChanged;
3 |
4 | public class ClassWithDependsOn :
5 | INotifyPropertyChanged
6 | {
7 | public string Property1 { get; set; }
8 | [DependsOn("Property1")]
9 | public string Property2 { get; set; }
10 | public event PropertyChangedEventHandler PropertyChanged;
11 | }
--------------------------------------------------------------------------------
/TestAssemblies/AssemblyToProcess/ClassWithDependsOnAndDoNotNotify.cs:
--------------------------------------------------------------------------------
1 | using System.ComponentModel;
2 | using PropertyChanged;
3 |
4 | public class ClassWithDependsOnAndDoNotNotify :
5 | INotifyPropertyChanged
6 | {
7 | [DoNotNotify]
8 | public string UseLessProperty { get; set; }
9 |
10 | public string Property1 { get; set; }
11 | public string Property2 => Property1;
12 |
13 | public event PropertyChangedEventHandler PropertyChanged;
14 | }
--------------------------------------------------------------------------------
/TestAssemblies/AssemblyToProcess/ClassWithDependsOnAndPropertyChanged.cs:
--------------------------------------------------------------------------------
1 | using System.ComponentModel;
2 | using PropertyChanged;
3 |
4 | public class ClassWithDependsOnAndPropertyChanged :
5 | INotifyPropertyChanged
6 | {
7 | public string Property1 { get; set; }
8 | [DependsOn("Property1")]
9 | public string Property2 { get; set; }
10 |
11 | public int Property2ChangedCalled = 0;
12 |
13 | private void OnProperty2Changed() => Property2ChangedCalled++;
14 |
15 |
16 | public event PropertyChangedEventHandler PropertyChanged;
17 | }
--------------------------------------------------------------------------------
/TestAssemblies/AssemblyToProcess/ClassWithDoNotNotify.cs:
--------------------------------------------------------------------------------
1 | using System.ComponentModel;
2 | using PropertyChanged;
3 |
4 | [DoNotNotify]
5 | public class ClassWithDoNotNotify :
6 | INotifyPropertyChanged
7 | {
8 | public event PropertyChangedEventHandler PropertyChanged;
9 | }
--------------------------------------------------------------------------------
/TestAssemblies/AssemblyToProcess/ClassWithDoNotNotifyField.cs:
--------------------------------------------------------------------------------
1 | using System.ComponentModel;
2 | using PropertyChanged;
3 |
4 | public class ClassWithDoNotNotifyField :
5 | INotifyPropertyChanged
6 | {
7 | [field: DoNotNotify]
8 | public string Property1 { get; set; }
9 |
10 | public event PropertyChangedEventHandler PropertyChanged;
11 | }
--------------------------------------------------------------------------------
/TestAssemblies/AssemblyToProcess/ClassWithDoNotSetChanged.cs:
--------------------------------------------------------------------------------
1 | using System.ComponentModel;
2 | using PropertyChanged;
3 |
4 | public class ClassWithDoNotSetChanged :
5 | INotifyPropertyChanged
6 | {
7 | [DoNotSetChanged]
8 | public string Property1 { get; set; }
9 |
10 | public bool IsChanged { get; set; }
11 |
12 | public event PropertyChangedEventHandler PropertyChanged;
13 | }
--------------------------------------------------------------------------------
/TestAssemblies/AssemblyToProcess/ClassWithExceptionInProperty.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.ComponentModel;
3 |
4 | public class ClassWithExceptionInProperty :
5 | INotifyPropertyChanged
6 | {
7 | public string Property
8 | {
9 | get => throw new NotImplementedException();
10 | set => throw new NotImplementedException();
11 | }
12 |
13 | public event PropertyChangedEventHandler PropertyChanged;
14 | }
--------------------------------------------------------------------------------
/TestAssemblies/AssemblyToProcess/ClassWithExplicitPropertyChanged.cs:
--------------------------------------------------------------------------------
1 | using System.ComponentModel;
2 |
3 | public class ClassWithExplicitPropertyChanged :
4 | INotifyPropertyChanged
5 | {
6 | // ReSharper disable NotAccessedField.Local
7 | PropertyChangedEventHandler propertyChanged;
8 | // ReSharper restore NotAccessedField.Local
9 |
10 | event PropertyChangedEventHandler INotifyPropertyChanged.PropertyChanged
11 | {
12 | add => propertyChanged += value;
13 | remove => propertyChanged -= value;
14 | }
15 |
16 | public string Property1 { get; set; }
17 | }
--------------------------------------------------------------------------------
/TestAssemblies/AssemblyToProcess/ClassWithExpression.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.ComponentModel;
3 | using System.Linq.Expressions;
4 | // ReSharper disable UnusedVariable
5 |
6 | public class ClassWithExpression :
7 | INotifyPropertyChanged
8 | {
9 | public string Property1;
10 |
11 | public ClassWithExpression()
12 | {
13 | Expression> expressionFunc = _ => _.Property1;
14 | Func func = _ => _.Property1;
15 |
16 | Action expression2 = (expression, s) => { expression.Property1 = s; };
17 | }
18 |
19 | public event PropertyChangedEventHandler PropertyChanged;
20 | }
--------------------------------------------------------------------------------
/TestAssemblies/AssemblyToProcess/ClassWithFieldGetButNoFieldSet.cs:
--------------------------------------------------------------------------------
1 | using System.ComponentModel;
2 |
3 | public class ClassWithFieldGetButNoFieldSet :
4 | INotifyPropertyChanged
5 | {
6 | string property;
7 |
8 | public string Property1
9 | {
10 | get => property;
11 | set => SetField(value);
12 | }
13 |
14 | void SetField(string value)
15 | {
16 | property = value;
17 | }
18 |
19 | public event PropertyChangedEventHandler PropertyChanged;
20 | }
--------------------------------------------------------------------------------
/TestAssemblies/AssemblyToProcess/ClassWithGeneratedPropertyChanged.cs:
--------------------------------------------------------------------------------
1 | using System.CodeDom.Compiler;
2 | using System.ComponentModel;
3 | using PropertyChanged;
4 |
5 | public class ClassWithGeneratedPropertyChangedBase;
6 |
7 | [AddINotifyPropertyChangedInterface]
8 | public class ClassWithGeneratedPropertyChanged : ClassWithGeneratedPropertyChangedBase, INotifyPropertyChanged
9 | {
10 | public string Property1 { get; set; }
11 |
12 | [GeneratedCode("PropertyChanged.Fody", "TEST")]
13 | public event PropertyChangedEventHandler PropertyChanged;
14 | }
--------------------------------------------------------------------------------
/TestAssemblies/AssemblyToProcess/ClassWithGenericAndLambda.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.ComponentModel;
3 | using System.Linq;
4 |
5 | public class ClassWithGenericAndLambda :
6 | INotifyPropertyChanged
7 | {
8 | public event PropertyChangedEventHandler PropertyChanged;
9 |
10 | public string Property1 { get; set; }
11 |
12 | public void MethodWithLambda(object data)
13 | {
14 | var list = new List