diff --git a/ICSharpCode.NRefactory.CSharp/ICSharpCode.NRefactory.CSharp.csproj b/ICSharpCode.NRefactory.CSharp/ICSharpCode.NRefactory.CSharp.csproj index 6aca802374..0650f3df4d 100644 --- a/ICSharpCode.NRefactory.CSharp/ICSharpCode.NRefactory.CSharp.csproj +++ b/ICSharpCode.NRefactory.CSharp/ICSharpCode.NRefactory.CSharp.csproj @@ -348,6 +348,7 @@ + diff --git a/ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/CreateFieldAction.cs b/ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/CreateFieldAction.cs index 6aff5de1dc..1a1e2d2d37 100644 --- a/ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/CreateFieldAction.cs +++ b/ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/CreateFieldAction.cs @@ -51,7 +51,7 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring if (!(context.Resolve(identifier).IsError)) { yield break; } - var guessedType = CreateFieldAction.GuessType(context, identifier); + var guessedType = CreateFieldAction.GuessAstType(context, identifier); if (guessedType == null) { yield break; } @@ -112,6 +112,21 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring return GetAllValidTypesFromInvokation(context, invoke, expr); } } + + if (expr.Parent is VariableInitializer) { + var initializer = (VariableInitializer)expr.Parent; + return new [] { context.Resolve(initializer).Type }; + } + + if (expr.Parent is CastExpression) { + var cast = (CastExpression)expr.Parent; + return new [] { context.Resolve(cast.Type).Type }; + } + + if (expr.Parent is AsExpression) { + var cast = (AsExpression)expr.Parent; + return new [] { context.Resolve(cast.Type).Type }; + } if (expr.Parent is AssignmentExpression) { var assign = (AssignmentExpression)expr.Parent; @@ -124,30 +139,43 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring var other = assign.Left == expr ? assign.Right : assign.Left; return new [] { context.Resolve(other).Type }; } - - return Enumerable.Empty(); - } - - internal static AstType GuessType(RefactoringContext context, IdentifierExpression identifier) - { - IType type = null; - foreach (var t in GetValidTypes(context, identifier)) { - if (type == null || type.GetAllBaseTypes().Contains(t)) { - type = t; - continue; + + if (expr.Parent is ReturnStatement) { + var state = context.GetResolverStateBefore(expr); + if (state != null) { + return new [] { state.CurrentMember.ReturnType }; } + } - if (!t.GetAllBaseTypes().Contains(type)) { - type = null; - break; + if (expr.Parent is YieldReturnStatement) { + var state = context.GetResolverStateBefore(expr); + if (state != null && (state.CurrentMember.ReturnType is ParameterizedType)) { + var pt = (ParameterizedType)state.CurrentMember.ReturnType; + if (pt.FullName == "System.Collections.Generic.IEnumerable") { + return new [] { pt.TypeArguments.First () }; + } } } - if (type == null) { + return Enumerable.Empty(); + } + + internal static AstType GuessAstType(RefactoringContext context, Expression expr) + { + var type = GetValidTypes(context, expr).ToArray(); + var inferedType = new TypeInference(context.Compilation).FindTypeInBounds(type, type); + if (inferedType.Kind == TypeKind.Unknown) { return new PrimitiveType("object"); } + return context.CreateShortType(inferedType); + } + + internal static IType GuessType(RefactoringContext context, Expression expr) + { + var type = GetValidTypes(context, expr).ToArray(); + var inferedType = new TypeInference(context.Compilation).FindTypeInBounds(type, type); + return inferedType; - return context.CreateShortType (type); } #endregion } diff --git a/ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/CreateLocalVariableAction.cs b/ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/CreateLocalVariableAction.cs index bfe6751284..24c7d3ed77 100644 --- a/ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/CreateLocalVariableAction.cs +++ b/ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/CreateLocalVariableAction.cs @@ -1,4 +1,4 @@ -// +// // CreateLocalVariable.cs // // Author: @@ -44,7 +44,7 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring if (!(context.Resolve(identifier).IsError)) { yield break; } - var guessedType = CreateFieldAction.GuessType(context, identifier); + var guessedType = CreateFieldAction.GuessAstType(context, identifier); if (guessedType == null) { yield break; } diff --git a/ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/CreateMethodDeclarationAction.cs b/ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/CreateMethodDeclarationAction.cs new file mode 100644 index 0000000000..2d73589a2e --- /dev/null +++ b/ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/CreateMethodDeclarationAction.cs @@ -0,0 +1,226 @@ +// +// CreateMethodDeclarationAction.cs +// +// Author: +// Mike Krüger +// +// Copyright (c) 2012 Xamarin +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +using System.Collections.Generic; +using System.Linq; +using ICSharpCode.NRefactory.Semantics; +using ICSharpCode.NRefactory.TypeSystem; +using System.Text; + +namespace ICSharpCode.NRefactory.CSharp.Refactoring +{ + [ContextAction("Create method", Description = "Creates a method declaration out of an invocation.")] + public class CreateMethodDeclarationAction : ICodeActionProvider + { + public IEnumerable GetActions(RefactoringContext context) + { + var invocation = context.GetNode(); + if (invocation != null) { + return GetActionsFromInvocation(context, invocation); + } + var identifier = context.GetNode(); + if (identifier != null) { + return GetActionsFromIdentifier(context, identifier); + } + return Enumerable.Empty(); + } + + public IEnumerable GetActionsFromIdentifier(RefactoringContext context, IdentifierExpression identifier) + { + if (!(context.Resolve(identifier).IsError)) { + yield break; + } + var methodName = identifier.Identifier; + var state = context.GetResolverStateBefore(identifier); + var guessedType = CreateFieldAction.GuessType(context, identifier); + if (guessedType.Kind != TypeKind.Delegate) { + yield break; + } + var invocationMethod = guessedType.GetDelegateInvokeMethod(); + + yield return new CodeAction(context.TranslateString("Create delegate handler"), script => { + var decl = new MethodDeclaration() { + ReturnType = context.CreateShortType(invocationMethod.ReturnType), + Name = methodName, + Body = new BlockStatement() { + new ThrowStatement(new ObjectCreateExpression(context.CreateShortType("System", "NotImplementedException"))) + } + }; + if (state.CurrentMember.IsStatic) { + decl.Modifiers |= Modifiers.Static; + } + + foreach (var parameter in invocationMethod.Parameters) { + decl.Parameters.Add(new ParameterDeclaration(context.CreateShortType (parameter.Type), parameter.Name) { + ParameterModifier = GetModifiers(parameter) + }); + } + script.InsertWithCursor(context.TranslateString("Create delegate handler"), decl, Script.InsertPosition.Before); + }); + + } + + static ParameterModifier GetModifiers(IParameter parameter) + { + if (parameter.IsOut) { + return ParameterModifier.Out; + } + if (parameter.IsRef) { + return ParameterModifier.Ref; + } + if (parameter.IsParams) { + return ParameterModifier.Params; + } + return ParameterModifier.None; + } + + public IEnumerable GetActionsFromInvocation(RefactoringContext context, InvocationExpression invocation) + { + if (!(context.Resolve(invocation.Target).IsError)) { + yield break; + } + + var methodName = GetMethodName(invocation); + if (methodName == null) { + yield break; + } + var state = context.GetResolverStateBefore(invocation); + var guessedType = invocation.Parent is ExpressionStatement ? new PrimitiveType("void") : CreateFieldAction.GuessAstType(context, invocation); + yield return new CodeAction(context.TranslateString("Create method"), script => { + var decl = new MethodDeclaration() { + ReturnType = guessedType, + Name = methodName, + Body = new BlockStatement() { + new ThrowStatement(new ObjectCreateExpression(context.CreateShortType("System", "NotImplementedException"))) + } + }; + if (invocation.Target is IdentifierExpression && state.CurrentMember.IsStatic) { + decl.Modifiers |= Modifiers.Static; + } + + foreach (var parameter in GenerateParameters (context, invocation)) { + decl.Parameters.Add(parameter); + } + script.InsertWithCursor(context.TranslateString("Create method"), decl, Script.InsertPosition.Before); + }); + } + + public IEnumerable GenerateParameters(RefactoringContext context, InvocationExpression invocation) + { + Dictionary nameCounter = new Dictionary(); + foreach (var argument in invocation.Arguments) { + ParameterModifier direction = ParameterModifier.None; + AstNode node; + if (argument is DirectionExpression) { + var de = (DirectionExpression)argument; + direction = de.FieldDirection == FieldDirection.Out ? ParameterModifier.Out : ParameterModifier.Ref; + node = de.Expression; + } else { + node = argument; + } + + var resolveResult = context.Resolve(node); + string name = CreateBaseName(argument, resolveResult.Type); + if (!nameCounter.ContainsKey(name)) { + nameCounter [name] = 1; + } else { + nameCounter [name]++; + name += nameCounter [name].ToString(); + } + var type = resolveResult.Type.Kind == TypeKind.Unknown ? new PrimitiveType("object") : context.CreateShortType(resolveResult.Type); + + yield return new ParameterDeclaration(type, name) { ParameterModifier = direction}; + } + } + + static string CreateBaseNameFromString(string str) + { + if (string.IsNullOrEmpty(str)) { + return "empty"; + } + var sb = new StringBuilder(); + bool firstLetter = true, wordStart = false; + foreach (char ch in str) { + if (char.IsWhiteSpace(ch)) { + wordStart = true; + continue; + } + if (!char.IsLetter(ch)) { + continue; + } + if (firstLetter) { + sb.Append(char.ToLower(ch)); + firstLetter = false; + continue; + } + if (wordStart) { + sb.Append(char.ToUpper(ch)); + wordStart = false; + continue; + } + sb.Append(ch); + } + return sb.Length == 0 ? "str" : sb.ToString(); + } + + static string CreateBaseName(AstNode node, IType type) + { + string name = null; + if (node is DirectionExpression) { + node = ((DirectionExpression)node).Expression; + } + + if (node is IdentifierExpression) { + name = ((IdentifierExpression)node).Identifier; + } else if (node is MemberReferenceExpression) { + name = ((MemberReferenceExpression)node).MemberName; + } else if (node is PrimitiveExpression) { + var pe = (PrimitiveExpression)node; + if (pe.Value is string) { + name = CreateBaseNameFromString(pe.Value.ToString()); + } + name = char.ToLower(type.Name [0]).ToString(); + } else { + name = type.Kind == TypeKind.Unknown ? "par" : type.Name; + } + + name = char.ToLower(name [0]) + name.Substring(1); + return name; + } + + public string GetMethodName(InvocationExpression invocation) + { + if (invocation.Target is IdentifierExpression) { + return ((IdentifierExpression)invocation.Target).Identifier; + } + if (invocation.Target is MemberReferenceExpression) { + return ((MemberReferenceExpression)invocation.Target).MemberName; + } + + return null; + } + } +} diff --git a/ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/CreatePropertyAction.cs b/ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/CreatePropertyAction.cs index bafb24710a..e8ff6add67 100644 --- a/ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/CreatePropertyAction.cs +++ b/ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/CreatePropertyAction.cs @@ -1,4 +1,4 @@ -// +// // CreateProperty.cs // // Author: @@ -48,7 +48,7 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring if (!(context.Resolve(identifier).IsError)) { yield break; } - var guessedType = CreateFieldAction.GuessType(context, identifier); + var guessedType = CreateFieldAction.GuessAstType(context, identifier); if (guessedType == null) { yield break; } diff --git a/ICSharpCode.NRefactory.Tests/CSharp/CodeActions/CreateLocalVariableTests.cs b/ICSharpCode.NRefactory.Tests/CSharp/CodeActions/CreateLocalVariableTests.cs index cfb23a02d5..8f4d22fae8 100644 --- a/ICSharpCode.NRefactory.Tests/CSharp/CodeActions/CreateLocalVariableTests.cs +++ b/ICSharpCode.NRefactory.Tests/CSharp/CodeActions/CreateLocalVariableTests.cs @@ -113,5 +113,62 @@ namespace ICSharpCode.NRefactory.CSharp.CodeActions " }" + Environment.NewLine + "}", result); } + + + [Test()] + public void TestReturn () + { + string result = RunContextAction ( + new CreateLocalVariableAction (), + "using System;" + Environment.NewLine + + "class TestClass" + Environment.NewLine + + "{" + Environment.NewLine + + " int Test ()" + Environment.NewLine + + " {" + Environment.NewLine + + " return $foo;" + Environment.NewLine + + " }" + Environment.NewLine + + "}" + ); + + Assert.AreEqual ( + "using System;" + Environment.NewLine + + "class TestClass" + Environment.NewLine + + "{" + Environment.NewLine + + " int Test ()" + Environment.NewLine + + " {" + Environment.NewLine + + " int foo;" + Environment.NewLine + + " return foo;" + Environment.NewLine + + " }" + Environment.NewLine + + "}", result); + } + + [Test()] + public void TestYieldReturn () + { + string result = RunContextAction ( + new CreateLocalVariableAction (), + "using System;" + Environment.NewLine + + "using System.Collections.Generic;" + Environment.NewLine + + "class TestClass" + Environment.NewLine + + "{" + Environment.NewLine + + " IEnumerable Test ()" + Environment.NewLine + + " {" + Environment.NewLine + + " yield return $foo;" + Environment.NewLine + + " }" + Environment.NewLine + + "}" + ); + + Assert.AreEqual ( + "using System;" + Environment.NewLine + + "using System.Collections.Generic;" + Environment.NewLine + + "class TestClass" + Environment.NewLine + + "{" + Environment.NewLine + + " IEnumerable Test ()" + Environment.NewLine + + " {" + Environment.NewLine + + " TestClass foo;" + Environment.NewLine + + " yield return foo;" + Environment.NewLine + + " }" + Environment.NewLine + + "}", result); + } } } \ No newline at end of file diff --git a/ICSharpCode.NRefactory.Tests/CSharp/CodeActions/CreateMethodDeclarationTests.cs b/ICSharpCode.NRefactory.Tests/CSharp/CodeActions/CreateMethodDeclarationTests.cs new file mode 100644 index 0000000000..535f55aba7 --- /dev/null +++ b/ICSharpCode.NRefactory.Tests/CSharp/CodeActions/CreateMethodDeclarationTests.cs @@ -0,0 +1,554 @@ +// +// CreateMethodDeclarationTests.cs +// +// Author: +// Mike Krüger +// +// Copyright (c) 2012 Xamarin +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +using System; +using NUnit.Framework; +using ICSharpCode.NRefactory.CSharp.Refactoring; +using System.Text; + +namespace ICSharpCode.NRefactory.CSharp.CodeActions +{ + [TestFixture] + public class CreateMethodDeclarationTests : ContextActionTestBase + { + static string HomogenizeEol (string str) + { + var sb = new StringBuilder (); + for (int i = 0; i < str.Length; i++) { + var ch = str [i]; + if (ch == '\n') { + sb.AppendLine (); + } else if (ch == '\r') { + sb.AppendLine (); + if (i + 1 < str.Length && str [i + 1] == '\n') + i++; + } else { + sb.Append (ch); + } + } + return sb.ToString (); + } + + public void TestCreateMethod (string input, string output) + { + string result = RunContextAction (new CreateMethodDeclarationAction (), HomogenizeEol (input)); + bool passed = result == output; + if (!passed) { + Console.WriteLine ("-----------Expected:"); + Console.WriteLine (output); + Console.WriteLine ("-----------Got:"); + Console.WriteLine (result); + } + Assert.AreEqual (HomogenizeEol (output), result); + } + + [Test()] + public void TestPrivateSimpleCreateMethod () + { + TestCreateMethod (@"class TestClass +{ + int member = 5; + string Test { get; set; } + + void TestMethod () + { + $NonExistantMethod (member, Test, 5); + } +}", @"class TestClass +{ + int member = 5; + string Test { get; set; } + + void NonExistantMethod (int member, string test, int i) + { + throw new System.NotImplementedException (); + } + void TestMethod () + { + NonExistantMethod (member, Test, 5); + } +}"); + } + + [Test()] + public void TestStaticSimpleCreateMethod () + { + TestCreateMethod (@"class TestClass +{ + public static void TestMethod () + { + int testLocalVar; + $NonExistantMethod (testLocalVar); + } +}", @"class TestClass +{ + static void NonExistantMethod (int testLocalVar) + { + throw new System.NotImplementedException (); + } + public static void TestMethod () + { + int testLocalVar; + NonExistantMethod (testLocalVar); + } +}"); + } + + [Test()] + public void TestGuessAssignmentReturnType () + { + TestCreateMethod (@"class TestClass +{ + static void TestMethod () + { + int testLocalVar = $NonExistantMethod (); + } +}", @"class TestClass +{ + static int NonExistantMethod () + { + throw new System.NotImplementedException (); + } + static void TestMethod () + { + int testLocalVar = NonExistantMethod (); + } +}"); + } + + [Test()] + public void TestGuessAssignmentReturnTypeCase2 () + { + TestCreateMethod (@"class TestClass +{ + static void TestMethod () + { + int testLocalVar; + testLocalVar = $NonExistantMethod (); + } +}", @"class TestClass +{ + static int NonExistantMethod () + { + throw new System.NotImplementedException (); + } + static void TestMethod () + { + int testLocalVar; + testLocalVar = NonExistantMethod (); + } +}"); + } + + [Test()] + public void TestGuessAssignmentReturnTypeCase3 () + { + TestCreateMethod (@"class TestClass +{ + static void TestMethod () + { + var testLocalVar = (string)$NonExistantMethod (); + } +}", @"class TestClass +{ + static string NonExistantMethod () + { + throw new System.NotImplementedException (); + } + static void TestMethod () + { + var testLocalVar = (string)NonExistantMethod (); + } +}"); + } + + + [Test()] + public void TestGuessParameterType () + { + TestCreateMethod (@"class TestClass +{ + void TestMethod () + { + Test ($NonExistantMethod ()); + } + void Test (int a) {} + +}", @"class TestClass +{ + int NonExistantMethod () + { + throw new System.NotImplementedException (); + } + void TestMethod () + { + Test (NonExistantMethod ()); + } + void Test (int a) {} + +}"); + } + + + [Test()] + public void TestCreateDelegateDeclaration () + { + TestCreateMethod (@"class TestClass +{ + public event MyDelegate MyEvent; + + void TestMethod () + { + MyEvent += $NonExistantMethod; + } +} + +public delegate string MyDelegate (int a, object b); +", @"class TestClass +{ + public event MyDelegate MyEvent; + + string NonExistantMethod (int a, object b) + { + throw new System.NotImplementedException (); + } + void TestMethod () + { + MyEvent += NonExistantMethod; + } +} + +public delegate string MyDelegate (int a, object b); +"); + } + + [Test()] + public void TestRefOutCreateMethod () + { + TestCreateMethod (@"class TestClass +{ + void TestMethod () + { + int a, b; + $NonExistantMethod (ref a, out b); + } +}", @"class TestClass +{ + void NonExistantMethod (ref int a, out int b) + { + throw new System.NotImplementedException (); + } + void TestMethod () + { + int a, b; + NonExistantMethod (ref a, out b); + } +}"); + } + + [Ignore("TODO")] + [Test()] + public void TestExternMethod () + { + TestCreateMethod ( +@" +class FooBar +{ +} + +class TestClass +{ + void TestMethod () + { + var fb = new FooBar (); + fb.$NonExistantMethod (); + } +} +", @" +class FooBar +{ + public void NonExistantMethod () + { + throw new System.NotImplementedException (); + } +} + +class TestClass +{ + void TestMethod () + { + var fb = new FooBar (); + fb.NonExistantMethod (); + } +} +"); + } + + [Ignore("TODO")] + [Test()] + public void TestCreateInterfaceMethod () + { + TestCreateMethod ( +@" +interface FooBar +{ +} + +class TestClass +{ + void TestMethod () + { + FooBar fb; + fb.$NonExistantMethod (); + } +} +", @" +interface FooBar +{ + void NonExistantMethod (); +} + +class TestClass +{ + void TestMethod () + { + FooBar fb; + fb.NonExistantMethod (); + } +} +"); + } + + [Ignore("TODO")] + [Test()] + public void TestCreateInStaticClassMethod () + { + TestCreateMethod ( +@" +static class FooBar +{ +} + +class TestClass +{ + void TestMethod () + { + FooBar.$NonExistantMethod (); + } +} +", @" +static class FooBar +{ + public static void NonExistantMethod () + { + throw new System.NotImplementedException (); + } +} + +class TestClass +{ + void TestMethod () + { + FooBar.NonExistantMethod (); + } +} +"); + } + + + + /// + /// Bug 677522 - "Create Method" creates at wrong indent level + /// + [Test()] + public void TestBug677522 () + { + TestCreateMethod ( +@"namespace Test { + class TestClass + { + void TestMethod () + { + $NonExistantMethod (); + } + } +} +", @"namespace Test { + class TestClass + { + void NonExistantMethod () + { + throw new System.NotImplementedException (); + } + void TestMethod () + { + NonExistantMethod (); + } + } +} +"); + } + + /// + /// Bug 677527 - "Create Method" uses fully qualified namespace when "using" statement exists + /// + [Test()] + public void TestBug677527 () + { + TestCreateMethod ( +@"using System.Text; + +namespace Test { + class TestClass + { + void TestMethod () + { + StringBuilder sb = new StringBuilder (); + $NonExistantMethod (sb); + } + } +} +", @"using System.Text; + +namespace Test { + class TestClass + { + void NonExistantMethod (StringBuilder sb) + { + throw new System.NotImplementedException (); + } + void TestMethod () + { + StringBuilder sb = new StringBuilder (); + NonExistantMethod (sb); + } + } +} +"); + } + + + /// + /// Bug 693949 - Create method uses the wrong type for param + /// + [Ignore("TODO")] + [Test()] + public void TestBug693949 () + { + // the c# code isn't 100% correct since test isn't accessible in Main (can't call non static method from static member) + TestCreateMethod ( +@"using System.Text; + +namespace Test { + class TestClass + { + string test(string a) + { + } + + public static void Main(string[] args) + { + Type a = $M(test(""a"")); + } + } +} +", @"using System.Text; + +namespace Test { + class TestClass + { + string test(string a) + { + } + + static Type M (string par1) + { + throw new System.NotImplementedException (); + } + + public static void Main(string[] args) + { + Type a = $M(test(""a"")); + } + } +} +"); + } + + /// + /// Bug 469 - CreateMethod created a method incorrectly + /// + [Test()] + public void TestBug469 () + { + TestCreateMethod ( +@"class Test +{ + public override string ToString () + { + $BeginDownloadingImage (this); + } +} +", @"class Test +{ + void BeginDownloadingImage (Test test) + { + throw new System.NotImplementedException (); + } + public override string ToString () + { + BeginDownloadingImage (this); + } +} +"); + } + + [Test()] + public void TestTestGuessReturnReturnType () + { + TestCreateMethod ( +@"class Test +{ + public override string ToString () + { + return $BeginDownloadingImage (this); + } +} +", @"class Test +{ + string BeginDownloadingImage (Test test) + { + throw new System.NotImplementedException (); + } + public override string ToString () + { + return BeginDownloadingImage (this); + } +} +"); + } + } +} + diff --git a/ICSharpCode.NRefactory.Tests/ICSharpCode.NRefactory.Tests.csproj b/ICSharpCode.NRefactory.Tests/ICSharpCode.NRefactory.Tests.csproj index 2198a16879..72e05c4ff8 100644 --- a/ICSharpCode.NRefactory.Tests/ICSharpCode.NRefactory.Tests.csproj +++ b/ICSharpCode.NRefactory.Tests/ICSharpCode.NRefactory.Tests.csproj @@ -252,6 +252,7 @@ +