Browse files

Added create method declaration action/use type inference to guess the

correct type.
  • Loading branch information...
1 parent 75b6cc6 commit 52ebb2641248e0485dd110a3ad77c8a8d1cb58a3 @mkrueger mkrueger committed Mar 26, 2012
View
1 ICSharpCode.NRefactory.CSharp/ICSharpCode.NRefactory.CSharp.csproj
@@ -348,6 +348,7 @@
<Compile Include="Refactoring\CodeIssues\InconsistentNamingIssue\AffectedEntity.cs" />
<Compile Include="Refactoring\CodeIssues\InconsistentNamingIssue\DefaultRules.cs" />
<Compile Include="Refactoring\CodeIssues\InconsistentNamingIssue\InconsistentNamingIssue.cs" />
+ <Compile Include="Refactoring\CodeActions\CreateMethodDeclarationAction.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\ICSharpCode.NRefactory\ICSharpCode.NRefactory.csproj">
View
62 ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/CreateFieldAction.cs
@@ -51,7 +51,7 @@ public IEnumerable<CodeAction> GetActions(RefactoringContext context)
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 @@ internal static IEnumerable<IType> GetValidTypes(RefactoringContext context, Exp
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 @@ internal static IEnumerable<IType> GetValidTypes(RefactoringContext context, Exp
var other = assign.Left == expr ? assign.Right : assign.Left;
return new [] { context.Resolve(other).Type };
}
-
- return Enumerable.Empty<IType>();
- }
-
- 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<IType>();
+ }
+
+ 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
}
View
4 ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/CreateLocalVariableAction.cs
@@ -1,4 +1,4 @@
-//
+//
// CreateLocalVariable.cs
//
// Author:
@@ -44,7 +44,7 @@ public IEnumerable<CodeAction> GetActions(RefactoringContext context)
if (!(context.Resolve(identifier).IsError)) {
yield break;
}
- var guessedType = CreateFieldAction.GuessType(context, identifier);
+ var guessedType = CreateFieldAction.GuessAstType(context, identifier);
if (guessedType == null) {
yield break;
}
View
226 ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/CreateMethodDeclarationAction.cs
@@ -0,0 +1,226 @@
+//
+// CreateMethodDeclarationAction.cs
+//
+// Author:
+// Mike Krüger <mkrueger@xamarin.com>
+//
+// Copyright (c) 2012 Xamarin <http://xamarin.com>
+//
+// 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<CodeAction> GetActions(RefactoringContext context)
+ {
+ var invocation = context.GetNode<InvocationExpression>();
+ if (invocation != null) {
+ return GetActionsFromInvocation(context, invocation);
+ }
+ var identifier = context.GetNode<IdentifierExpression>();
+ if (identifier != null) {
+ return GetActionsFromIdentifier(context, identifier);
+ }
+ return Enumerable.Empty<CodeAction>();
+ }
+
+ public IEnumerable<CodeAction> 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<CodeAction> 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<ParameterDeclaration> GenerateParameters(RefactoringContext context, InvocationExpression invocation)
+ {
+ Dictionary<string, int> nameCounter = new Dictionary<string, int>();
+ 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;
+ }
+ }
+}
View
4 ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/CreatePropertyAction.cs
@@ -1,4 +1,4 @@
-//
+//
// CreateProperty.cs
//
// Author:
@@ -48,7 +48,7 @@ public IEnumerable<CodeAction> GetActions(RefactoringContext context)
if (!(context.Resolve(identifier).IsError)) {
yield break;
}
- var guessedType = CreateFieldAction.GuessType(context, identifier);
+ var guessedType = CreateFieldAction.GuessAstType(context, identifier);
if (guessedType == null) {
yield break;
}
View
57 ICSharpCode.NRefactory.Tests/CSharp/CodeActions/CreateLocalVariableTests.cs
@@ -113,5 +113,62 @@ public void TestOutParamCall ()
" }" + 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<TestClass> 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<TestClass> Test ()" + Environment.NewLine +
+ " {" + Environment.NewLine +
+ " TestClass foo;" + Environment.NewLine +
+ " yield return foo;" + Environment.NewLine +
+ " }" + Environment.NewLine +
+ "}", result);
+ }
}
}
View
554 ICSharpCode.NRefactory.Tests/CSharp/CodeActions/CreateMethodDeclarationTests.cs
@@ -0,0 +1,554 @@
+//
+// CreateMethodDeclarationTests.cs
+//
+// Author:
+// Mike Krüger <mkrueger@xamarin.com>
+//
+// Copyright (c) 2012 Xamarin <http://xamarin.com>
+//
+// 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 ();
+ }
+}
+");
+ }
+
+
+
+ /// <summary>
+ /// Bug 677522 - "Create Method" creates at wrong indent level
+ /// </summary>
+ [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 ();
+ }
+ }
+}
+");
+ }
+
+ /// <summary>
+ /// Bug 677527 - "Create Method" uses fully qualified namespace when "using" statement exists
+ /// </summary>
+ [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);
+ }
+ }
+}
+");
+ }
+
+
+ /// <summary>
+ /// Bug 693949 - Create method uses the wrong type for param
+ /// </summary>
+ [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""));
+ }
+ }
+}
+");
+ }
+
+ /// <summary>
+ /// Bug 469 - CreateMethod created a method incorrectly
+ /// </summary>
+ [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);
+ }
+}
+");
+ }
+ }
+}
+
View
1 ICSharpCode.NRefactory.Tests/ICSharpCode.NRefactory.Tests.csproj
@@ -252,6 +252,7 @@
<Compile Include="CSharp\CodeActions\CreateLocalVariableTests.cs" />
<Compile Include="CSharp\CodeActions\CreateFieldTests.cs" />
<Compile Include="CSharp\CodeActions\CreatePropertyTests.cs" />
+ <Compile Include="CSharp\CodeActions\CreateMethodDeclarationTests.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\Mono.Cecil\Mono.Cecil.csproj">

0 comments on commit 52ebb26

Please sign in to comment.