From 522d6c6cbdea97c3a45c21b0e0993a4deae20c13 Mon Sep 17 00:00:00 2001 From: Simon Lindgren Date: Fri, 27 Jul 2012 10:31:22 +0200 Subject: [PATCH] [CodeActions] Fix bugs in ConvertToInitializer. --- .../StatementsToInitializerConverter.cs | 21 +++++--- .../ConvertToInitializerTests.cs | 52 ++++++++++++++++--- 2 files changed, 59 insertions(+), 14 deletions(-) diff --git a/ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/ConvertToInitializer/StatementsToInitializerConverter.cs b/ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/ConvertToInitializer/StatementsToInitializerConverter.cs index c0e093d26f..ef2314aaf8 100644 --- a/ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/ConvertToInitializer/StatementsToInitializerConverter.cs +++ b/ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/ConvertToInitializer/StatementsToInitializerConverter.cs @@ -159,7 +159,9 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring var initializerPath = InitializerPath.FromResolveResult(argumentLocalResolveResult); if (initializerPath == null || !initializers.ContainsKey(initializerPath)) return false; - tuple.Elements.Add(initializers[initializerPath]); + // Add a clone, since we do not yet know if this is where the initializer will be used + var initializerClone = initializers[initializerPath].Clone(); + tuple.Elements.Add(initializerClone); } else { tuple.Elements.Add(argument.Clone()); } @@ -167,6 +169,8 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring ReplacementNodeHelper.AddReplacementAnnotation(tuple, expressionStatement); var targetPath = InitializerPath.FromResolveResult(targetResult); + if (targetPath == null || !initializers.ContainsKey(targetPath)) + return false; InsertImplicitInitializersForPath(targetPath); var targetInitializer = initializers [targetPath]; AddToInitializer(targetInitializer, tuple); @@ -196,12 +200,14 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring var rightResolveResult = context.Resolve(initializer) as LocalResolveResult; if (rightResolveResult != null) { var rightPath = InitializerPath.FromResolveResult(rightResolveResult); - var rightInitializer = initializers [rightPath]; - if (rightInitializer != null) { - rightInitializer.AddAnnotation(new ReplacementNodeAnnotation() { ReplacedNode = node }); + if (rightPath != null && initializers.ContainsKey(rightPath)) { + var rightInitializer = initializers [rightPath]; + ReplacementNodeHelper.AddReplacementAnnotation(rightInitializer, node); initializers.Remove(rightPath); initializers [variablePath] = rightInitializer; - mainInitializerPath = variablePath; + if (rightPath == mainInitializerPath) { + mainInitializerPath = variablePath; + } } } else { initializers [variablePath] = ReplacementNodeHelper.CloneWithReplacementAnnotation(initializer, node); @@ -223,7 +229,6 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring { var rightResolveResult = context.Resolve(right) as LocalResolveResult; var leftResolveResult = context.Resolve(left); - var leftPath = InitializerPath.FromResolveResult(leftResolveResult); Expression initializer; if (rightResolveResult != null) { var rightPath = InitializerPath.FromResolveResult(rightResolveResult); @@ -235,6 +240,10 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring } else { initializer = right.Clone(); } + var leftPath = InitializerPath.FromResolveResult(leftResolveResult); + if (leftPath == null) { + return false; + } // Move replacement annotations over, in case this is the second assignment // to the same variable. AddOldAnnotationsToInitializer(leftPath, initializer); diff --git a/ICSharpCode.NRefactory.Tests/CSharp/CodeActions/ConvertToInitializer/ConvertToInitializerTests.cs b/ICSharpCode.NRefactory.Tests/CSharp/CodeActions/ConvertToInitializer/ConvertToInitializerTests.cs index 2c18486cb7..de63f3c5da 100644 --- a/ICSharpCode.NRefactory.Tests/CSharp/CodeActions/ConvertToInitializer/ConvertToInitializerTests.cs +++ b/ICSharpCode.NRefactory.Tests/CSharp/CodeActions/ConvertToInitializer/ConvertToInitializerTests.cs @@ -114,14 +114,14 @@ class TestClass }", baseText + @" var tc0 = new TestClass(); var collection = new System.Collections.Generic.Dictionary () { - {""string1"", new TestClass() { Property = ""tc1""}}, - {""string2"", new TestClass() { Property = ""tc2""}} + {""string1"", new TestClass() { Property = ""tc1"" }}, + {""string2"", new TestClass() { Property = ""tc2"" }} }; collection.Add(""string0"", tc0); } }"); } - + [Test] public void CollectionOfObjects() { @@ -151,6 +151,25 @@ class TestClass } }"); } + + [Test] + public void UnknownTargetForAdd() + { + Test(baseText + @" + var collection = new System.Collections.Generic.List (); + var item $= new TestClass (); + item.Property = ""Value1""; + collection.Add(item); + } +}", baseText + @" + var collection = new System.Collections.Generic.List (); + var item = new TestClass() { + Property = ""Value1"" + }; + collection.Add(item); + } +}"); + } [Test] public void ObjectContainingCollections() @@ -479,10 +498,9 @@ class TestClass Nested = new TestClass() }; } -}" - ); +}"); } - + [Test] public void HandlesAssignmentToFinalVariable() { @@ -496,8 +514,26 @@ class TestClass Property = ""Value"" }; } -}" - ); +}"); + } + + [Test] + public void FinalVariableAssignmentOfOtherInitializer() + { + Test(baseText + @" + var tc $= new TestClass (); + tc.Property = ""Value""; + var _variable = new TestClass (); + var variable = _variable; + } +}", baseText + @" + var tc = new TestClass () { + Property = ""Value"" + }; + var _variable = new Test$Class (); + var variable = _variable; + } +}"); } [Test]