diff --git a/ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/ConvertCastToAsAction.cs b/ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/ConvertCastToAsAction.cs index 85c694bd71..5aecc69d82 100644 --- a/ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/ConvertCastToAsAction.cs +++ b/ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/ConvertCastToAsAction.cs @@ -34,7 +34,7 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring [ContextAction ("Convert cast to 'as'.", Description = "Convert cast to 'as'.")] public class ConvertCastToAsAction : SpecializedCodeAction { - + static InsertParenthesesVisitor insertParentheses = new InsertParenthesesVisitor (); protected override CodeAction GetAction (RefactoringContext context, CastExpression node) { if (node.Expression.Contains (context.Location)) @@ -42,10 +42,23 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring // only works on reference and nullable types var type = context.ResolveType (node.Type); var typeDef = type.GetDefinition (); - if (type.IsReferenceType == true || (typeDef != null && typeDef.KnownTypeCode == KnownTypeCode.NullableOfT)) - return new CodeAction (context.TranslateString ("Convert cast to 'as'"), script => - script.Replace (node, new AsExpression (node.Expression.Clone (), node.Type.Clone ()))); - + var isNullable = typeDef != null && typeDef.KnownTypeCode == KnownTypeCode.NullableOfT; + if (type.IsReferenceType == true || isNullable) { + return new CodeAction (context.TranslateString ("Convert cast to 'as'"), script => { + var asExpr = new AsExpression (node.Expression.Clone (), node.Type.Clone ()); + // if parent is an expression, clone parent and replace the case expression with asExpr, + // so that we can inset parentheses + var parentExpr = node.Parent.Clone () as Expression; + if (parentExpr != null) { + var castExpr = parentExpr.GetNodeContaining (node.StartLocation, node.EndLocation); + castExpr.ReplaceWith (asExpr); + parentExpr.AcceptVisitor (insertParentheses); + script.Replace (node.Parent, parentExpr); + } else { + script.Replace (node, asExpr); + } + }); + } return null; } } diff --git a/ICSharpCode.NRefactory.Tests/CSharp/CodeActions/ConvertCastToAsTests.cs b/ICSharpCode.NRefactory.Tests/CSharp/CodeActions/ConvertCastToAsTests.cs index f25a0c9653..3ab5a801f4 100644 --- a/ICSharpCode.NRefactory.Tests/CSharp/CodeActions/ConvertCastToAsTests.cs +++ b/ICSharpCode.NRefactory.Tests/CSharp/CodeActions/ConvertCastToAsTests.cs @@ -32,7 +32,7 @@ namespace ICSharpCode.NRefactory.CSharp.CodeActions [TestFixture] public class ConvertCastToAsTests : ContextActionTestBase { - void TestType(string type) + void TestType (string type) { string input = @" using System; @@ -56,19 +56,19 @@ class TestClass } [Test] - public void Test() + public void Test () { TestType ("Exception"); } [Test] - public void TestNullable() + public void TestNullable () { TestType ("int?"); } [Test] - public void TestNonReferenceType() + public void TestNonReferenceType () { TestWrongContext (@" using System; @@ -76,9 +76,29 @@ class TestClass { void Test (object a) { - var b = (int)$a; + var b = ($int)a; } }"); } + + [Test] + public void TestInsertParentheses () + { + string input = @" +class TestClass { + void TestMethod (object o) + { + var b = 1 + ($TestClass)o; + } +}"; + string output = @" +class TestClass { + void TestMethod (object o) + { + var b = 1 + (o as TestClass); + } +}"; + Test (input, output); + } } }