diff --git a/src/Microsoft.CodeQuality.Analyzers/Core/MicrosoftCodeQualityAnalyzersResources.resx b/src/Microsoft.CodeQuality.Analyzers/Core/MicrosoftCodeQualityAnalyzersResources.resx
index 5fc9391b6a..302c58cfc6 100644
--- a/src/Microsoft.CodeQuality.Analyzers/Core/MicrosoftCodeQualityAnalyzersResources.resx
+++ b/src/Microsoft.CodeQuality.Analyzers/Core/MicrosoftCodeQualityAnalyzersResources.resx
@@ -1334,4 +1334,13 @@
The property {0} should not be assigned to itself.
+
+ Assigning to a symbol and its member (field/property) in the same statement is not recommended. It is not clear if the member access was intended to use symbol's old value prior to the assignment or new value from the assignment in this statement. For clarity, consider splitting the assignments into separate statements.
+
+
+ Symbol '{0}' and its member '{1}' are both assigned in the same statement. You are at risk of assigning the member of an unintended object.
+
+
+ Assigning symbol and its member in the same statement.
+
\ No newline at end of file
diff --git a/src/Microsoft.CodeQuality.Analyzers/Core/QualityGuidelines/AssigningSymbolAndItsMemberInSameStatement.cs b/src/Microsoft.CodeQuality.Analyzers/Core/QualityGuidelines/AssigningSymbolAndItsMemberInSameStatement.cs
new file mode 100644
index 0000000000..aa73798712
--- /dev/null
+++ b/src/Microsoft.CodeQuality.Analyzers/Core/QualityGuidelines/AssigningSymbolAndItsMemberInSameStatement.cs
@@ -0,0 +1,100 @@
+// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System;
+using System.Collections.Immutable;
+using Analyzer.Utilities;
+using Microsoft.CodeAnalysis;
+using Microsoft.CodeAnalysis.Diagnostics;
+using Microsoft.CodeAnalysis.Operations;
+
+namespace Microsoft.CodeQuality.Analyzers.QualityGuidelines
+{
+ ///
+ /// CA2246: Prevent objects from being referenced in statements where they are reassigned
+ ///
+ [DiagnosticAnalyzer(LanguageNames.CSharp)]
+ public sealed class AssigningSymbolAndItsMemberInSameStatement : DiagnosticAnalyzer
+ {
+ internal const string RuleId = "CA2246";
+
+ private static readonly LocalizableString s_localizableTitle = new LocalizableResourceString(nameof(MicrosoftCodeQualityAnalyzersResources.AssigningSymbolAndItsMemberInSameStatementTitle), MicrosoftCodeQualityAnalyzersResources.ResourceManager, typeof(MicrosoftCodeQualityAnalyzersResources));
+ private static readonly LocalizableString s_localizableMessage = new LocalizableResourceString(nameof(MicrosoftCodeQualityAnalyzersResources.AssigningSymbolAndItsMemberInSameStatementMessage), MicrosoftCodeQualityAnalyzersResources.ResourceManager, typeof(MicrosoftCodeQualityAnalyzersResources));
+ private static readonly LocalizableString s_localizableDescription = new LocalizableResourceString(nameof(MicrosoftCodeQualityAnalyzersResources.AssigningSymbolAndItsMemberInSameStatementDescription), MicrosoftCodeQualityAnalyzersResources.ResourceManager, typeof(MicrosoftCodeQualityAnalyzersResources));
+
+ internal static DiagnosticDescriptor Rule = new DiagnosticDescriptor(RuleId,
+ s_localizableTitle,
+ s_localizableMessage,
+ DiagnosticCategory.Usage,
+ DiagnosticHelpers.DefaultDiagnosticSeverity,
+ DiagnosticHelpers.EnabledByDefaultIfNotBuildingVSIX,
+ s_localizableDescription);
+
+ public override ImmutableArray SupportedDiagnostics => ImmutableArray.Create(Rule);
+
+ public override void Initialize(AnalysisContext context)
+ {
+ context.EnableConcurrentExecution();
+ context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None);
+
+ context.RegisterOperationAction(AnalyzeAssignment, OperationKind.SimpleAssignment);
+ }
+
+ private void AnalyzeAssignment(OperationAnalysisContext context)
+ {
+ var assignmentOperation = (ISimpleAssignmentOperation)context.Operation;
+
+ // Check if there are more then one assignment in a statement
+ if (!(assignmentOperation.Target is IMemberReferenceOperation operationTarget))
+ {
+ return;
+ }
+
+ // This analyzer makes sense only for reference type objects
+ if (operationTarget.Instance?.Type.IsValueType == true)
+ {
+ return;
+ }
+
+ // Search for object equal to operationTarget.Instance further in assignment chain
+ bool isViolationFound = false;
+ if (operationTarget.Instance is ILocalReferenceOperation localInstance)
+ {
+ isViolationFound = AnalyzeAssignmentToMember(assignmentOperation, localInstance, (a, b) => a.Local.Equals(b.Local));
+ }
+ else if (operationTarget.Instance is IMemberReferenceOperation memberInstance)
+ {
+ isViolationFound = AnalyzeAssignmentToMember(assignmentOperation, memberInstance, (a, b) => a.Member.Equals(b.Member) && a.Instance?.Syntax.ToString() == b.Instance?.Syntax.ToString());
+ }
+ else if (operationTarget.Instance is IParameterReferenceOperation parameterInstance)
+ {
+ isViolationFound = AnalyzeAssignmentToMember(assignmentOperation, parameterInstance, (a, b) => a.Parameter.Equals(b.Parameter));
+ }
+ else
+ {
+ return;
+ }
+
+ if (isViolationFound)
+ {
+ var diagnostic = Diagnostic.Create(Rule, operationTarget.Syntax.GetLocation(), operationTarget.Instance.Syntax, operationTarget.Member.Name);
+ context.ReportDiagnostic(diagnostic);
+ }
+ }
+
+ private static bool AnalyzeAssignmentToMember(ISimpleAssignmentOperation assignmentOperation, T instance, Func equalityComparer) where T : class, IOperation
+ {
+ // Check every simple assignments target in a statement for equality to `instance`
+ while (assignmentOperation.Value.Kind == OperationKind.SimpleAssignment)
+ {
+ assignmentOperation = (ISimpleAssignmentOperation)assignmentOperation.Value;
+
+ var operationValue = assignmentOperation.Target as T;
+ if (equalityComparer(instance, operationValue))
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+ }
+}
diff --git a/src/Microsoft.CodeQuality.Analyzers/Core/xlf/MicrosoftCodeQualityAnalyzersResources.cs.xlf b/src/Microsoft.CodeQuality.Analyzers/Core/xlf/MicrosoftCodeQualityAnalyzersResources.cs.xlf
index 429a2e0ffc..04e41a7c3e 100644
--- a/src/Microsoft.CodeQuality.Analyzers/Core/xlf/MicrosoftCodeQualityAnalyzersResources.cs.xlf
+++ b/src/Microsoft.CodeQuality.Analyzers/Core/xlf/MicrosoftCodeQualityAnalyzersResources.cs.xlf
@@ -7,6 +7,21 @@
Připojit .ConfigureAwait(true)
+
+
+ Assigning to a symbol and its member (field/property) in the same statement is not recommended. It is not clear if the member access was intended to use symbol's old value prior to the assignment or new value from the assignment in this statement. For clarity, consider splitting the assignments into separate statements.
+
+
+
+
+ Symbol '{0}' and its member '{1}' are both assigned in the same statement. You are at risk of assigning the member of an unintended object.
+
+
+
+
+ Assigning symbol and its member in the same statement.
+
+ Vyhněte se Async Void.
diff --git a/src/Microsoft.CodeQuality.Analyzers/Core/xlf/MicrosoftCodeQualityAnalyzersResources.de.xlf b/src/Microsoft.CodeQuality.Analyzers/Core/xlf/MicrosoftCodeQualityAnalyzersResources.de.xlf
index eee1e1abab..b57851f6b0 100644
--- a/src/Microsoft.CodeQuality.Analyzers/Core/xlf/MicrosoftCodeQualityAnalyzersResources.de.xlf
+++ b/src/Microsoft.CodeQuality.Analyzers/Core/xlf/MicrosoftCodeQualityAnalyzersResources.de.xlf
@@ -7,6 +7,21 @@
"ConfigureAwait(true)" anfügen
+
+
+ Assigning to a symbol and its member (field/property) in the same statement is not recommended. It is not clear if the member access was intended to use symbol's old value prior to the assignment or new value from the assignment in this statement. For clarity, consider splitting the assignments into separate statements.
+
+
+
+
+ Symbol '{0}' and its member '{1}' are both assigned in the same statement. You are at risk of assigning the member of an unintended object.
+
+
+
+
+ Assigning symbol and its member in the same statement.
+
+ Async Void vermeiden
diff --git a/src/Microsoft.CodeQuality.Analyzers/Core/xlf/MicrosoftCodeQualityAnalyzersResources.es.xlf b/src/Microsoft.CodeQuality.Analyzers/Core/xlf/MicrosoftCodeQualityAnalyzersResources.es.xlf
index 166e4cb384..a0aef542d9 100644
--- a/src/Microsoft.CodeQuality.Analyzers/Core/xlf/MicrosoftCodeQualityAnalyzersResources.es.xlf
+++ b/src/Microsoft.CodeQuality.Analyzers/Core/xlf/MicrosoftCodeQualityAnalyzersResources.es.xlf
@@ -7,6 +7,21 @@
Anexar .ConfigureAwait(true)
+
+
+ Assigning to a symbol and its member (field/property) in the same statement is not recommended. It is not clear if the member access was intended to use symbol's old value prior to the assignment or new value from the assignment in this statement. For clarity, consider splitting the assignments into separate statements.
+
+
+
+
+ Symbol '{0}' and its member '{1}' are both assigned in the same statement. You are at risk of assigning the member of an unintended object.
+
+
+
+
+ Assigning symbol and its member in the same statement.
+
+ Evitar async void
diff --git a/src/Microsoft.CodeQuality.Analyzers/Core/xlf/MicrosoftCodeQualityAnalyzersResources.fr.xlf b/src/Microsoft.CodeQuality.Analyzers/Core/xlf/MicrosoftCodeQualityAnalyzersResources.fr.xlf
index dbf3088ede..34d10025a9 100644
--- a/src/Microsoft.CodeQuality.Analyzers/Core/xlf/MicrosoftCodeQualityAnalyzersResources.fr.xlf
+++ b/src/Microsoft.CodeQuality.Analyzers/Core/xlf/MicrosoftCodeQualityAnalyzersResources.fr.xlf
@@ -7,6 +7,21 @@
Ajouter .ConfigureAwait(true)
+
+
+ Assigning to a symbol and its member (field/property) in the same statement is not recommended. It is not clear if the member access was intended to use symbol's old value prior to the assignment or new value from the assignment in this statement. For clarity, consider splitting the assignments into separate statements.
+
+
+
+
+ Symbol '{0}' and its member '{1}' are both assigned in the same statement. You are at risk of assigning the member of an unintended object.
+
+
+
+
+ Assigning symbol and its member in the same statement.
+
+ Éviter Async Void
diff --git a/src/Microsoft.CodeQuality.Analyzers/Core/xlf/MicrosoftCodeQualityAnalyzersResources.it.xlf b/src/Microsoft.CodeQuality.Analyzers/Core/xlf/MicrosoftCodeQualityAnalyzersResources.it.xlf
index baf56acf31..91fc429240 100644
--- a/src/Microsoft.CodeQuality.Analyzers/Core/xlf/MicrosoftCodeQualityAnalyzersResources.it.xlf
+++ b/src/Microsoft.CodeQuality.Analyzers/Core/xlf/MicrosoftCodeQualityAnalyzersResources.it.xlf
@@ -7,6 +7,21 @@
Accoda .ConfigureAwait(true)
+
+
+ Assigning to a symbol and its member (field/property) in the same statement is not recommended. It is not clear if the member access was intended to use symbol's old value prior to the assignment or new value from the assignment in this statement. For clarity, consider splitting the assignments into separate statements.
+
+
+
+
+ Symbol '{0}' and its member '{1}' are both assigned in the same statement. You are at risk of assigning the member of an unintended object.
+
+
+
+
+ Assigning symbol and its member in the same statement.
+
+ Evitare metodi asincroni void
diff --git a/src/Microsoft.CodeQuality.Analyzers/Core/xlf/MicrosoftCodeQualityAnalyzersResources.ja.xlf b/src/Microsoft.CodeQuality.Analyzers/Core/xlf/MicrosoftCodeQualityAnalyzersResources.ja.xlf
index 6d732b023c..2c24cd26e1 100644
--- a/src/Microsoft.CodeQuality.Analyzers/Core/xlf/MicrosoftCodeQualityAnalyzersResources.ja.xlf
+++ b/src/Microsoft.CodeQuality.Analyzers/Core/xlf/MicrosoftCodeQualityAnalyzersResources.ja.xlf
@@ -7,6 +7,21 @@
.ConfigureAwait(true) を追加します
+
+
+ Assigning to a symbol and its member (field/property) in the same statement is not recommended. It is not clear if the member access was intended to use symbol's old value prior to the assignment or new value from the assignment in this statement. For clarity, consider splitting the assignments into separate statements.
+
+
+
+
+ Symbol '{0}' and its member '{1}' are both assigned in the same statement. You are at risk of assigning the member of an unintended object.
+
+
+
+
+ Assigning symbol and its member in the same statement.
+
+ Async Void を使用しないでください
diff --git a/src/Microsoft.CodeQuality.Analyzers/Core/xlf/MicrosoftCodeQualityAnalyzersResources.ko.xlf b/src/Microsoft.CodeQuality.Analyzers/Core/xlf/MicrosoftCodeQualityAnalyzersResources.ko.xlf
index 6479de034d..1419222343 100644
--- a/src/Microsoft.CodeQuality.Analyzers/Core/xlf/MicrosoftCodeQualityAnalyzersResources.ko.xlf
+++ b/src/Microsoft.CodeQuality.Analyzers/Core/xlf/MicrosoftCodeQualityAnalyzersResources.ko.xlf
@@ -7,6 +7,21 @@
.ConfigureAwait(true) 추가
+
+
+ Assigning to a symbol and its member (field/property) in the same statement is not recommended. It is not clear if the member access was intended to use symbol's old value prior to the assignment or new value from the assignment in this statement. For clarity, consider splitting the assignments into separate statements.
+
+
+
+
+ Symbol '{0}' and its member '{1}' are both assigned in the same statement. You are at risk of assigning the member of an unintended object.
+
+
+
+
+ Assigning symbol and its member in the same statement.
+
+ Async Void를 사용하지 마세요.
diff --git a/src/Microsoft.CodeQuality.Analyzers/Core/xlf/MicrosoftCodeQualityAnalyzersResources.pl.xlf b/src/Microsoft.CodeQuality.Analyzers/Core/xlf/MicrosoftCodeQualityAnalyzersResources.pl.xlf
index aef0bba149..e7fed8d697 100644
--- a/src/Microsoft.CodeQuality.Analyzers/Core/xlf/MicrosoftCodeQualityAnalyzersResources.pl.xlf
+++ b/src/Microsoft.CodeQuality.Analyzers/Core/xlf/MicrosoftCodeQualityAnalyzersResources.pl.xlf
@@ -7,6 +7,21 @@
Dołącz element .ConfigureAwait(true)
+
+
+ Assigning to a symbol and its member (field/property) in the same statement is not recommended. It is not clear if the member access was intended to use symbol's old value prior to the assignment or new value from the assignment in this statement. For clarity, consider splitting the assignments into separate statements.
+
+
+
+
+ Symbol '{0}' and its member '{1}' are both assigned in the same statement. You are at risk of assigning the member of an unintended object.
+
+
+
+
+ Assigning symbol and its member in the same statement.
+
+ Unikaj metod async void
diff --git a/src/Microsoft.CodeQuality.Analyzers/Core/xlf/MicrosoftCodeQualityAnalyzersResources.pt-BR.xlf b/src/Microsoft.CodeQuality.Analyzers/Core/xlf/MicrosoftCodeQualityAnalyzersResources.pt-BR.xlf
index ea6ab6a1ce..dc5bf3b9dd 100644
--- a/src/Microsoft.CodeQuality.Analyzers/Core/xlf/MicrosoftCodeQualityAnalyzersResources.pt-BR.xlf
+++ b/src/Microsoft.CodeQuality.Analyzers/Core/xlf/MicrosoftCodeQualityAnalyzersResources.pt-BR.xlf
@@ -7,6 +7,21 @@
Acrescentar .ConfigureAwait(true)
+
+
+ Assigning to a symbol and its member (field/property) in the same statement is not recommended. It is not clear if the member access was intended to use symbol's old value prior to the assignment or new value from the assignment in this statement. For clarity, consider splitting the assignments into separate statements.
+
+
+
+
+ Symbol '{0}' and its member '{1}' are both assigned in the same statement. You are at risk of assigning the member of an unintended object.
+
+
+
+
+ Assigning symbol and its member in the same statement.
+
+ Evitar async void
diff --git a/src/Microsoft.CodeQuality.Analyzers/Core/xlf/MicrosoftCodeQualityAnalyzersResources.ru.xlf b/src/Microsoft.CodeQuality.Analyzers/Core/xlf/MicrosoftCodeQualityAnalyzersResources.ru.xlf
index 7a18bac8fb..4c8e6ae113 100644
--- a/src/Microsoft.CodeQuality.Analyzers/Core/xlf/MicrosoftCodeQualityAnalyzersResources.ru.xlf
+++ b/src/Microsoft.CodeQuality.Analyzers/Core/xlf/MicrosoftCodeQualityAnalyzersResources.ru.xlf
@@ -7,6 +7,21 @@
Добавить .ConfigureAwait(true)
+
+
+ Assigning to a symbol and its member (field/property) in the same statement is not recommended. It is not clear if the member access was intended to use symbol's old value prior to the assignment or new value from the assignment in this statement. For clarity, consider splitting the assignments into separate statements.
+
+
+
+
+ Symbol '{0}' and its member '{1}' are both assigned in the same statement. You are at risk of assigning the member of an unintended object.
+
+
+
+
+ Assigning symbol and its member in the same statement.
+
+ Избегание Async Void
diff --git a/src/Microsoft.CodeQuality.Analyzers/Core/xlf/MicrosoftCodeQualityAnalyzersResources.tr.xlf b/src/Microsoft.CodeQuality.Analyzers/Core/xlf/MicrosoftCodeQualityAnalyzersResources.tr.xlf
index 7b0d6f4647..49d772185a 100644
--- a/src/Microsoft.CodeQuality.Analyzers/Core/xlf/MicrosoftCodeQualityAnalyzersResources.tr.xlf
+++ b/src/Microsoft.CodeQuality.Analyzers/Core/xlf/MicrosoftCodeQualityAnalyzersResources.tr.xlf
@@ -7,6 +7,21 @@
Ekle .ConfigureAwait(true)
+
+
+ Assigning to a symbol and its member (field/property) in the same statement is not recommended. It is not clear if the member access was intended to use symbol's old value prior to the assignment or new value from the assignment in this statement. For clarity, consider splitting the assignments into separate statements.
+
+
+
+
+ Symbol '{0}' and its member '{1}' are both assigned in the same statement. You are at risk of assigning the member of an unintended object.
+
+
+
+
+ Assigning symbol and its member in the same statement.
+
+ Async Void Kullanmayın
diff --git a/src/Microsoft.CodeQuality.Analyzers/Core/xlf/MicrosoftCodeQualityAnalyzersResources.zh-Hans.xlf b/src/Microsoft.CodeQuality.Analyzers/Core/xlf/MicrosoftCodeQualityAnalyzersResources.zh-Hans.xlf
index bedc87ede3..6ad957d082 100644
--- a/src/Microsoft.CodeQuality.Analyzers/Core/xlf/MicrosoftCodeQualityAnalyzersResources.zh-Hans.xlf
+++ b/src/Microsoft.CodeQuality.Analyzers/Core/xlf/MicrosoftCodeQualityAnalyzersResources.zh-Hans.xlf
@@ -7,6 +7,21 @@
附加 .ConfigureAwait(true)
+
+
+ Assigning to a symbol and its member (field/property) in the same statement is not recommended. It is not clear if the member access was intended to use symbol's old value prior to the assignment or new value from the assignment in this statement. For clarity, consider splitting the assignments into separate statements.
+
+
+
+
+ Symbol '{0}' and its member '{1}' are both assigned in the same statement. You are at risk of assigning the member of an unintended object.
+
+
+
+
+ Assigning symbol and its member in the same statement.
+
+ 避免使用 Async Void
diff --git a/src/Microsoft.CodeQuality.Analyzers/Core/xlf/MicrosoftCodeQualityAnalyzersResources.zh-Hant.xlf b/src/Microsoft.CodeQuality.Analyzers/Core/xlf/MicrosoftCodeQualityAnalyzersResources.zh-Hant.xlf
index e4f37856e6..d535b6895d 100644
--- a/src/Microsoft.CodeQuality.Analyzers/Core/xlf/MicrosoftCodeQualityAnalyzersResources.zh-Hant.xlf
+++ b/src/Microsoft.CodeQuality.Analyzers/Core/xlf/MicrosoftCodeQualityAnalyzersResources.zh-Hant.xlf
@@ -7,6 +7,21 @@
附加 .ConfigureAwait(true)
+
+
+ Assigning to a symbol and its member (field/property) in the same statement is not recommended. It is not clear if the member access was intended to use symbol's old value prior to the assignment or new value from the assignment in this statement. For clarity, consider splitting the assignments into separate statements.
+
+
+
+
+ Symbol '{0}' and its member '{1}' are both assigned in the same statement. You are at risk of assigning the member of an unintended object.
+
+
+
+
+ Assigning symbol and its member in the same statement.
+
+ 避免 Async Void
diff --git a/src/Microsoft.CodeQuality.Analyzers/UnitTests/QualityGuidelines/AssigningSymbolAndItsMemberInSameStatementTests.cs b/src/Microsoft.CodeQuality.Analyzers/UnitTests/QualityGuidelines/AssigningSymbolAndItsMemberInSameStatementTests.cs
new file mode 100644
index 0000000000..e9dfdf21a1
--- /dev/null
+++ b/src/Microsoft.CodeQuality.Analyzers/UnitTests/QualityGuidelines/AssigningSymbolAndItsMemberInSameStatementTests.cs
@@ -0,0 +1,320 @@
+// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using Microsoft.CodeAnalysis.Diagnostics;
+using Microsoft.CodeQuality.Analyzers.QualityGuidelines;
+using Test.Utilities;
+using Xunit;
+
+namespace Microsoft.CodeQuality.Analyzers.UnitTests.QualityGuidelines
+{
+ public partial class AssigningSymbolAndItsMemberInSameStatementTests : DiagnosticAnalyzerTestBase
+ {
+ protected override DiagnosticAnalyzer GetBasicDiagnosticAnalyzer()
+ {
+ return new AssigningSymbolAndItsMemberInSameStatement();
+ }
+
+ protected override DiagnosticAnalyzer GetCSharpDiagnosticAnalyzer()
+ {
+ return new AssigningSymbolAndItsMemberInSameStatement();
+ }
+
+ [Fact]
+ public void CSharpReassignLocalVariableAndReferToItsField()
+ {
+ VerifyCSharp(@"
+public class C
+{
+ public C Field;
+}
+
+public class Test
+{
+ public void Method()
+ {
+ C a = new C(), b = new C();
+ a.Field = a = b;
+ }
+}
+",
+ GetCSharpResultAt(12, 9, AssigningSymbolAndItsMemberInSameStatement.Rule, "a", "Field"));
+ }
+
+ [Fact]
+ public void CSharpReassignLocalVariableAndReferToItsProperty()
+ {
+ VerifyCSharp(@"
+public class C
+{
+ public C Property { get; set; }
+}
+
+public class Test
+{
+ public void Method()
+ {
+ C a = new C(), b = new C(), c;
+ a.Property = c = a = b;
+ }
+}
+",
+ GetCSharpResultAt(12, 9, AssigningSymbolAndItsMemberInSameStatement.Rule, "a", "Property"));
+ }
+
+ [Fact]
+ public void CSharpReassignLocalVariablesPropertyAndReferToItsProperty()
+ {
+ VerifyCSharp(@"
+public class C
+{
+ public C Property { get; set; }
+}
+
+public class Test
+{
+ public void Method()
+ {
+ C a = new C(), b = new C();
+ a.Property.Property = a.Property = b;
+ }
+}
+",
+ GetCSharpResultAt(12, 9, AssigningSymbolAndItsMemberInSameStatement.Rule, "a.Property", "Property"));
+ }
+
+ [Fact]
+ public void CSharpReassignLocalVariableAndItsPropertyAndReferToItsProperty()
+ {
+ VerifyCSharp(@"
+public class C
+{
+ public C Property { get; set; }
+}
+
+public class Test
+{
+ public void Method()
+ {
+ C a = new C(), b = new C();
+ a.Property.Property = a.Property = a = b;
+ }
+}
+",
+ GetCSharpResultAt(12, 9, AssigningSymbolAndItsMemberInSameStatement.Rule, "a.Property", "Property"),
+ GetCSharpResultAt(12, 31, AssigningSymbolAndItsMemberInSameStatement.Rule, "a", "Property"));
+ }
+
+ [Fact]
+ public void CSharpReferToFieldOfReferenceTypeLocalVariableAfterItsReassignment()
+ {
+ VerifyCSharp(@"
+public class C
+{
+ public C Field;
+}
+
+public class Test
+{
+ static C x, y;
+
+ public void Method()
+ {
+ x.Field = x = y;
+ }
+}
+",
+ GetCSharpResultAt(13, 9, AssigningSymbolAndItsMemberInSameStatement.Rule, "x", "Field"));
+ }
+
+ [Fact]
+ public void CSharpReassignGlobalVariableAndReferToItsField()
+ {
+ VerifyCSharp(@"
+public class C
+{
+ public C Property { get; set; }
+}
+
+public class Test
+{
+ static C x, y;
+
+ public void Method()
+ {
+ x.Property.Property = x.Property = y;
+ }
+}
+",
+ GetCSharpResultAt(13, 9, AssigningSymbolAndItsMemberInSameStatement.Rule, "x.Property", "Property"));
+ }
+
+ [Fact]
+ public void CSharpReassignGlobalVariableAndItsPropertyAndReferToItsProperty()
+ {
+ VerifyCSharp(@"
+public class C
+{
+ public C Property { get; set; }
+}
+
+public class Test
+{
+ static C x, y;
+
+ public void Method()
+ {
+ x.Property.Property = x.Property = x = y;
+ }
+}
+",
+ GetCSharpResultAt(13, 9, AssigningSymbolAndItsMemberInSameStatement.Rule, "x.Property", "Property"),
+ GetCSharpResultAt(13, 31, AssigningSymbolAndItsMemberInSameStatement.Rule, "x", "Property"));
+ }
+
+
+ [Fact]
+ public void CSharpReassignGlobalPropertyAndItsPropertyAndReferToItsProperty()
+ {
+ VerifyCSharp(@"
+public class C
+{
+ public C Property { get; set; }
+}
+
+public class Test
+{
+ static C x { get; set; }
+ static C y { get; set; }
+
+ public void Method()
+ {
+ x.Property.Property = x.Property = x = y;
+ }
+}
+",
+ GetCSharpResultAt(14, 9, AssigningSymbolAndItsMemberInSameStatement.Rule, "x.Property", "Property"),
+ GetCSharpResultAt(14, 31, AssigningSymbolAndItsMemberInSameStatement.Rule, "x", "Property"));
+ }
+
+ [Fact]
+ public void CSharpReassignSecondLocalVariableAndReferToItsPropertyOfFirstVariable()
+ {
+ VerifyCSharp(@"
+public class C
+{
+ public C Property { get; set; }
+}
+
+public class Test
+{
+ public void Method()
+ {
+ C a = new C(), b;
+ a.Property = b = a;
+ }
+}
+");
+ }
+
+ [Fact]
+ public void CSharpReassignPropertyOfFirstLocalVariableWithSecondAndReferToPropertyOfSecondVariable()
+ {
+ VerifyCSharp(@"
+public class C
+{
+ public C Property { get; set; }
+}
+
+public class Test
+{
+ public void Method()
+ {
+ C a = new C(), b = new C(), c;
+ b.Property.Property = a.Property = b;
+ }
+}
+");
+ }
+
+ [Fact]
+ public void CSharpReassignPropertyOfFirstLocalVariableWithThirdAndReferToPropertyOfSecondVariable()
+ {
+ VerifyCSharp(@"
+public class C
+{
+ public C Property { get; set; }
+}
+
+public class Test
+{
+ public void Method()
+ {
+ C a = new C(), b = new C(), c = new C();
+ b.Property.Property = a.Property = c;
+ }
+}
+");
+ }
+
+ [Fact]
+ public void CSharpReassignMethodParameterAndReferToItsProperty()
+ {
+ VerifyCSharp(@"
+public class C
+{
+ public C Property { get; set; }
+}
+
+public class Test
+{
+ public void Method(C b)
+ {
+ C a = new C();
+ b.Property = b = a;
+ }
+}
+",
+ GetCSharpResultAt(12, 9, AssigningSymbolAndItsMemberInSameStatement.Rule, "b", "Property"));
+ }
+
+ [Fact]
+ public void CSharpReassignLocalValueTypeVariableAndReferToItsField()
+ {
+ VerifyCSharp(@"
+public struct S
+{
+ public S Field;
+}
+
+public class Test
+{
+ public void Method()
+ {
+ S a, b;
+ a.Field = a = b;
+ }
+}
+", TestValidationMode.AllowCompileErrors);
+ }
+
+ [Fact]
+ public void CSharpReassignLocalValueTypeVariableAndReferToItsProperty()
+ {
+ VerifyCSharp(@"
+public struct S
+{
+ public S Property { get; set; }
+}
+
+public class Test
+{
+ public void Method()
+ {
+ S a, b;
+ a.Property = c = a = b;
+ }
+}
+", TestValidationMode.AllowCompileErrors);
+ }
+ }
+}