9 changed files with 759 additions and 5 deletions
@ -0,0 +1,185 @@
@@ -0,0 +1,185 @@
|
||||
//
|
||||
// ExtractMethodAction.cs
|
||||
//
|
||||
// Author:
|
||||
// Mike Krüger <mkrueger@xamarin.com>
|
||||
//
|
||||
// Copyright (c) 2012 Xamarin Inc. (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 System.Collections.Generic; |
||||
using ICSharpCode.NRefactory.Semantics; |
||||
using System.Linq; |
||||
using ICSharpCode.NRefactory.CSharp.Resolver; |
||||
using ICSharpCode.NRefactory.CSharp.Analysis; |
||||
using System.Threading; |
||||
using ICSharpCode.NRefactory.TypeSystem; |
||||
|
||||
namespace ICSharpCode.NRefactory.CSharp.Refactoring.ExtractMethod |
||||
{ |
||||
[ContextAction("Extract method", Description = "Creates a new method out of selected text.")] |
||||
public class ExtractMethodAction : ICodeActionProvider |
||||
{ |
||||
public IEnumerable<CodeAction> GetActions(RefactoringContext context) |
||||
{ |
||||
if (!context.IsSomethingSelected) |
||||
yield break; |
||||
var selected = new List<AstNode>(context.GetSelectedNodes()); |
||||
if (selected.Count == 0) |
||||
yield break; |
||||
|
||||
if (selected.Count == 1 && selected [0] is Expression) { |
||||
var codeAction = CreateFromExpression(context, (Expression)selected [0]); |
||||
if (codeAction == null) |
||||
yield break; |
||||
yield return codeAction; |
||||
} |
||||
|
||||
foreach (var node in selected) { |
||||
if (!(node is Statement)) |
||||
yield break; |
||||
} |
||||
|
||||
yield return CreateFromStatements(context, new List<Statement> (selected.OfType<Statement> ())); |
||||
} |
||||
|
||||
CodeAction CreateFromExpression(RefactoringContext context, Expression expression) |
||||
{ |
||||
var resolveResult = context.Resolve(expression); |
||||
if (resolveResult.IsError) |
||||
return null; |
||||
|
||||
return new CodeAction(context.TranslateString("Extract method"), script => { |
||||
string methodName = "NewMethod"; |
||||
var method = new MethodDeclaration() { |
||||
ReturnType = context.CreateShortType(resolveResult.Type), |
||||
Name = methodName, |
||||
Body = new BlockStatement() { |
||||
new ReturnStatement(expression.Clone()) |
||||
} |
||||
}; |
||||
if (!StaticVisitor.UsesNotStaticMember(context, expression)) |
||||
method.Modifiers |= Modifiers.Static; |
||||
script.InsertWithCursor(context.TranslateString("Extract method"), method, Script.InsertPosition.Before); |
||||
var target = new IdentifierExpression(methodName); |
||||
script.Replace(expression, new InvocationExpression(target)); |
||||
script.Link(target, method.NameToken); |
||||
}); |
||||
} |
||||
|
||||
CodeAction CreateFromStatements(RefactoringContext context, List<Statement> statements) |
||||
{ |
||||
if (!(statements [0].Parent is Statement)) |
||||
return null; |
||||
|
||||
return new CodeAction(context.TranslateString("Extract method"), script => { |
||||
string methodName = "NewMethod"; |
||||
var method = new MethodDeclaration() { |
||||
ReturnType = new PrimitiveType("void"), |
||||
Name = methodName, |
||||
Body = new BlockStatement() |
||||
}; |
||||
bool usesNonStaticMember = false; |
||||
foreach (Statement node in statements) { |
||||
usesNonStaticMember |= StaticVisitor.UsesNotStaticMember(context, node); |
||||
method.Body.Add(node.Clone()); |
||||
} |
||||
if (!usesNonStaticMember) |
||||
method.Modifiers |= Modifiers.Static; |
||||
|
||||
var target = new IdentifierExpression(methodName); |
||||
var invocation = new InvocationExpression(target); |
||||
|
||||
var usedVariables = VariableLookupVisitor.Analyze(context, statements); |
||||
|
||||
var extractedCodeAnalysis = new DefiniteAssignmentAnalysis((Statement)statements [0].Parent, context.Resolver, context.CancellationToken); |
||||
var lastStatement = statements [statements.Count - 1]; |
||||
extractedCodeAnalysis.SetAnalyzedRange(statements [0], lastStatement); |
||||
var statusAfterMethod = new List<Tuple<IVariable, DefiniteAssignmentStatus>>(); |
||||
|
||||
foreach (var variable in usedVariables) { |
||||
extractedCodeAnalysis.Analyze(variable.Name, DefiniteAssignmentStatus.PotentiallyAssigned, context.CancellationToken); |
||||
statusAfterMethod.Add(Tuple.Create(variable, extractedCodeAnalysis.GetStatusAfter(lastStatement))); |
||||
} |
||||
var stmt = statements [0].GetParent<BlockStatement>(); |
||||
while (stmt.GetParent<BlockStatement> () != null) { |
||||
stmt = stmt.GetParent<BlockStatement>(); |
||||
} |
||||
|
||||
var wholeCodeAnalysis = new DefiniteAssignmentAnalysis(stmt, context.Resolver, context.CancellationToken); |
||||
var statusBeforeMethod = new Dictionary<IVariable, DefiniteAssignmentStatus>(); |
||||
foreach (var variable in usedVariables) { |
||||
wholeCodeAnalysis.Analyze(variable.Name, DefiniteAssignmentStatus.PotentiallyAssigned, context.CancellationToken); |
||||
statusBeforeMethod [variable] = extractedCodeAnalysis.GetStatusBefore(statements [0]); |
||||
} |
||||
|
||||
var afterCodeAnalysis = new DefiniteAssignmentAnalysis(stmt, context.Resolver, context.CancellationToken); |
||||
var statusAtEnd = new Dictionary<IVariable, DefiniteAssignmentStatus>(); |
||||
afterCodeAnalysis.SetAnalyzedRange(lastStatement, stmt.Statements.Last(), false, true); |
||||
|
||||
foreach (var variable in usedVariables) { |
||||
afterCodeAnalysis.Analyze(variable.Name, DefiniteAssignmentStatus.PotentiallyAssigned, context.CancellationToken); |
||||
statusBeforeMethod [variable] = extractedCodeAnalysis.GetStatusBefore(statements [0]); |
||||
} |
||||
var beforeVisitor = new VariableLookupVisitor(context); |
||||
beforeVisitor.SetAnalyzedRange(stmt, statements [0], true, false); |
||||
stmt.AcceptVisitor(beforeVisitor); |
||||
var afterVisitor = new VariableLookupVisitor(context); |
||||
afterVisitor.SetAnalyzedRange(lastStatement, stmt, false, true); |
||||
stmt.AcceptVisitor(afterVisitor); |
||||
|
||||
foreach (var status in statusAfterMethod) { |
||||
if (!beforeVisitor.UsedVariables.Contains(status.Item1) && !afterVisitor.UsedVariables.Contains(status.Item1)) |
||||
continue; |
||||
Expression argumentExpression = new IdentifierExpression(status.Item1.Name); |
||||
|
||||
ParameterModifier mod; |
||||
switch (status.Item2) { |
||||
case DefiniteAssignmentStatus.AssignedAfterTrueExpression: |
||||
case DefiniteAssignmentStatus.AssignedAfterFalseExpression: |
||||
case DefiniteAssignmentStatus.PotentiallyAssigned: |
||||
mod = ParameterModifier.Ref; |
||||
argumentExpression = new DirectionExpression(FieldDirection.Ref, argumentExpression); |
||||
break; |
||||
case DefiniteAssignmentStatus.DefinitelyAssigned: |
||||
if (statusBeforeMethod [status.Item1] != DefiniteAssignmentStatus.PotentiallyAssigned) |
||||
goto case DefiniteAssignmentStatus.PotentiallyAssigned; |
||||
mod = ParameterModifier.Out; |
||||
argumentExpression = new DirectionExpression(FieldDirection.Out, argumentExpression); |
||||
break; |
||||
// case DefiniteAssignmentStatus.Unassigned:
|
||||
default: |
||||
mod = ParameterModifier.None; |
||||
break; |
||||
} |
||||
method.Parameters.Add(new ParameterDeclaration(context.CreateShortType(status.Item1.Type), status.Item1.Name, mod)); |
||||
invocation.Arguments.Add(argumentExpression); |
||||
} |
||||
|
||||
script.InsertWithCursor(context.TranslateString("Extract method"), method, Script.InsertPosition.Before); |
||||
foreach (var node in statements.Skip (1)) { |
||||
script.Remove(node); |
||||
} |
||||
script.Replace(statements [0], new ExpressionStatement(invocation)); |
||||
script.Link(target, method.NameToken); |
||||
}); |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,85 @@
@@ -0,0 +1,85 @@
|
||||
//
|
||||
// StaticVisitor.cs
|
||||
//
|
||||
// Author:
|
||||
// Mike Krüger <mkrueger@xamarin.com>
|
||||
//
|
||||
// Copyright (c) 2012 Xamarin Inc. (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 ICSharpCode.NRefactory.Semantics; |
||||
using System.Linq; |
||||
using ICSharpCode.NRefactory.CSharp.Resolver; |
||||
|
||||
namespace ICSharpCode.NRefactory.CSharp.Refactoring.ExtractMethod |
||||
{ |
||||
class StaticVisitor : DepthFirstAstVisitor |
||||
{ |
||||
readonly RefactoringContext context; |
||||
public bool UsesNonStaticMember = false; |
||||
|
||||
StaticVisitor(RefactoringContext context) |
||||
{ |
||||
this.context = context; |
||||
} |
||||
|
||||
|
||||
public static bool UsesNotStaticMember(RefactoringContext context, AstNode node) |
||||
{ |
||||
var visitor = new StaticVisitor(context); |
||||
node.AcceptVisitor(visitor); |
||||
return visitor.UsesNonStaticMember; |
||||
} |
||||
|
||||
protected override void VisitChildren(AstNode node) |
||||
{ |
||||
if (UsesNonStaticMember) |
||||
return; |
||||
base.VisitChildren(node); |
||||
} |
||||
|
||||
public override void VisitThisReferenceExpression(ThisReferenceExpression thisReferenceExpression) |
||||
{ |
||||
UsesNonStaticMember = true; |
||||
base.VisitThisReferenceExpression(thisReferenceExpression); |
||||
} |
||||
|
||||
public override void VisitBaseReferenceExpression(BaseReferenceExpression baseReferenceExpression) |
||||
{ |
||||
UsesNonStaticMember = true; |
||||
base.VisitBaseReferenceExpression(baseReferenceExpression); |
||||
} |
||||
|
||||
public override void VisitIdentifierExpression(IdentifierExpression identifierExpression) |
||||
{ |
||||
var resolveResult = context.Resolve(identifierExpression); |
||||
if (resolveResult is MemberResolveResult) { |
||||
var memberResult = (MemberResolveResult)resolveResult; |
||||
if (!memberResult.Member.IsStatic) |
||||
UsesNonStaticMember = true; |
||||
} else if (resolveResult is MethodGroupResolveResult) { |
||||
var methodGroupResolveResult = (MethodGroupResolveResult)resolveResult; |
||||
if (methodGroupResolveResult.Methods.Any(m => !m.IsStatic)) |
||||
UsesNonStaticMember = true; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,97 @@
@@ -0,0 +1,97 @@
|
||||
//
|
||||
// VariableLookupVisitor.cs
|
||||
//
|
||||
// Author:
|
||||
// Mike Krüger <mkrueger@xamarin.com>
|
||||
//
|
||||
// Copyright (c) 2012 Xamarin Inc. (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 System.Collections.Generic; |
||||
using ICSharpCode.NRefactory.Semantics; |
||||
using ICSharpCode.NRefactory.TypeSystem; |
||||
|
||||
namespace ICSharpCode.NRefactory.CSharp.Refactoring.ExtractMethod |
||||
{ |
||||
class VariableLookupVisitor : DepthFirstAstVisitor |
||||
{ |
||||
readonly RefactoringContext context; |
||||
|
||||
public List<IVariable> UsedVariables = new List<IVariable> (); |
||||
|
||||
TextLocation startLocation = TextLocation.Empty; |
||||
TextLocation endLocation = TextLocation.Empty; |
||||
|
||||
|
||||
public VariableLookupVisitor (RefactoringContext context) |
||||
{ |
||||
this.context = context; |
||||
} |
||||
|
||||
public void SetAnalyzedRange(AstNode start, AstNode end, bool startInclusive = true, bool endInclusive = true) |
||||
{ |
||||
if (start == null) |
||||
throw new ArgumentNullException("start"); |
||||
if (end == null) |
||||
throw new ArgumentNullException("end"); |
||||
startLocation = startInclusive ? start.StartLocation : start.EndLocation; |
||||
endLocation = endInclusive ? end.EndLocation : end.StartLocation; |
||||
} |
||||
|
||||
public override void VisitIdentifierExpression(IdentifierExpression identifierExpression) |
||||
{ |
||||
if (startLocation.IsEmpty || startLocation <= identifierExpression.StartLocation && identifierExpression.EndLocation <= endLocation) { |
||||
var result = context.Resolve(identifierExpression); |
||||
var local = result as LocalResolveResult; |
||||
if (local != null && !UsedVariables.Contains(local.Variable)) |
||||
UsedVariables.Add(local.Variable); |
||||
} |
||||
} |
||||
|
||||
public override void VisitVariableDeclarationStatement(VariableDeclarationStatement variableDeclarationStatement) |
||||
{ |
||||
base.VisitVariableDeclarationStatement(variableDeclarationStatement); |
||||
foreach (var varDecl in variableDeclarationStatement.Variables) { |
||||
if (startLocation.IsEmpty || startLocation <= varDecl.StartLocation && varDecl.EndLocation <= endLocation) { |
||||
var result = context.Resolve(varDecl); |
||||
var local = result as LocalResolveResult; |
||||
if (local != null && !UsedVariables.Contains(local.Variable)) |
||||
UsedVariables.Add(local.Variable); |
||||
} |
||||
} |
||||
} |
||||
|
||||
|
||||
public static List<IVariable> Analyze(RefactoringContext context, Expression expression) |
||||
{ |
||||
var visitor = new VariableLookupVisitor(context); |
||||
expression.AcceptVisitor(visitor); |
||||
return visitor.UsedVariables; |
||||
} |
||||
|
||||
public static List<IVariable> Analyze(RefactoringContext context, List<Statement> statements) |
||||
{ |
||||
var visitor = new VariableLookupVisitor(context); |
||||
statements.ForEach(stmt => stmt.AcceptVisitor(visitor)); |
||||
return visitor.UsedVariables; |
||||
} |
||||
} |
||||
} |
||||
|
||||
@ -0,0 +1,373 @@
@@ -0,0 +1,373 @@
|
||||
//
|
||||
// ExtractMethodTests.cs
|
||||
//
|
||||
// Author:
|
||||
// Mike Krüger <mkrueger@xamarin.com>
|
||||
//
|
||||
// Copyright (c) 2012 Xamarin Inc. (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 NUnit.Framework; |
||||
using ICSharpCode.NRefactory.CSharp.Refactoring.ExtractMethod; |
||||
|
||||
namespace ICSharpCode.NRefactory.CSharp.CodeActions |
||||
{ |
||||
[TestFixture] |
||||
public class ExtractMethodTests : ContextActionTestBase |
||||
{ |
||||
|
||||
[Ignore("FIXME!!")] |
||||
[Test()] |
||||
public void ExtractMethodResultStatementTest() |
||||
{ |
||||
Test<ExtractMethodAction>(@"class TestClass
|
||||
{ |
||||
int member = 5; |
||||
void TestMethod () |
||||
{ |
||||
int i = 5; |
||||
<-i = member + 1;-> |
||||
Console.WriteLine (i); |
||||
} |
||||
} |
||||
", @"class TestClass |
||||
{ |
||||
int member = 5; |
||||
void NewMethod (ref int i) |
||||
{ |
||||
i = member + 1; |
||||
} |
||||
void TestMethod () |
||||
{ |
||||
int i = 5; |
||||
NewMethod (ref i); |
||||
Console.WriteLine (i); |
||||
} |
||||
} |
||||
");
|
||||
} |
||||
|
||||
[Test()] |
||||
public void ExtractMethodResultExpressionTest() |
||||
{ |
||||
Test<ExtractMethodAction>(@"class TestClass
|
||||
{ |
||||
int member = 5; |
||||
void TestMethod () |
||||
{ |
||||
int i = <-member + 1->; |
||||
Console.WriteLine (i); |
||||
} |
||||
} |
||||
", @"class TestClass |
||||
{ |
||||
int member = 5; |
||||
int NewMethod () |
||||
{ |
||||
return member + 1; |
||||
} |
||||
void TestMethod () |
||||
{ |
||||
int i = NewMethod (); |
||||
Console.WriteLine (i); |
||||
} |
||||
} |
||||
");
|
||||
} |
||||
|
||||
[Ignore("FIXME!!")] |
||||
[Test()] |
||||
public void ExtractMethodStaticResultStatementTest() |
||||
{ |
||||
Test<ExtractMethodAction>(@"class TestClass
|
||||
{ |
||||
void TestMethod () |
||||
{ |
||||
int i = 5; |
||||
<-i = i + 1;-> |
||||
Console.WriteLine (i); |
||||
} |
||||
} |
||||
", @"class TestClass |
||||
{ |
||||
static void NewMethod (ref int i) |
||||
{ |
||||
i = i + 1; |
||||
} |
||||
void TestMethod () |
||||
{ |
||||
int i = 5; |
||||
NewMethod (ref i); |
||||
Console.WriteLine (i); |
||||
} |
||||
} |
||||
");
|
||||
} |
||||
|
||||
[Test()] |
||||
public void ExtractMethodStaticResultExpressionTest() |
||||
{ |
||||
Test<ExtractMethodAction>(@"class TestClass
|
||||
{ |
||||
void TestMethod () |
||||
{ |
||||
int i = <-5 + 1->; |
||||
Console.WriteLine (i); |
||||
} |
||||
} |
||||
", @"class TestClass |
||||
{ |
||||
static int NewMethod () |
||||
{ |
||||
return 5 + 1; |
||||
} |
||||
void TestMethod () |
||||
{ |
||||
int i = NewMethod (); |
||||
Console.WriteLine (i); |
||||
} |
||||
} |
||||
");
|
||||
} |
||||
|
||||
[Ignore("FIXME!!")] |
||||
[Test()] |
||||
public void ExtractMethodMultiVariableTest() |
||||
{ |
||||
Test<ExtractMethodAction>(@"class TestClass
|
||||
{ |
||||
int member; |
||||
void TestMethod () |
||||
{ |
||||
int i = 5, j = 10, k; |
||||
<-j = i + j; |
||||
k = j + member;-> |
||||
Console.WriteLine (k + j); |
||||
} |
||||
} |
||||
", @"class TestClass |
||||
{ |
||||
int member; |
||||
void NewMethod (ref int j, int i, out int k) |
||||
{ |
||||
j = i + j; |
||||
k = j + member; |
||||
} |
||||
void TestMethod () |
||||
{ |
||||
int i = 5, j = 10, k; |
||||
NewMethod (i, ref j, out k); |
||||
Console.WriteLine (k + j); |
||||
} |
||||
} |
||||
");
|
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Bug 607990 - "Extract Method" refactoring sometimes tries to pass in unnecessary parameter depending on selection
|
||||
/// </summary>
|
||||
[Test()] |
||||
public void TestBug607990() |
||||
{ |
||||
Test<ExtractMethodAction>(@"class TestClass
|
||||
{ |
||||
void TestMethod () |
||||
{ |
||||
<-Object obj1 = new Object(); |
||||
obj1.ToString();-> |
||||
} |
||||
} |
||||
", @"class TestClass |
||||
{ |
||||
static void NewMethod () |
||||
{ |
||||
Object obj1 = new Object (); |
||||
obj1.ToString (); |
||||
} |
||||
void TestMethod () |
||||
{ |
||||
NewMethod (); |
||||
} |
||||
} |
||||
");
|
||||
} |
||||
|
||||
|
||||
/// <summary>
|
||||
/// Bug 616193 - Extract method passes param with does not exists any more in main method
|
||||
/// </summary>
|
||||
[Ignore("FIXME!!")] |
||||
[Test()] |
||||
public void TestBug616193() |
||||
{ |
||||
Test<ExtractMethodAction>(@"class TestClass
|
||||
{ |
||||
void TestMethod () |
||||
{ |
||||
string ret; |
||||
string x; |
||||
int y; |
||||
<-string z = ret + y; |
||||
ret = x + z;-> |
||||
} |
||||
} |
||||
", @"class TestClass |
||||
{ |
||||
static void NewMethod (out string ret, string x, int y) |
||||
{ |
||||
string z = ret + y; |
||||
ret = x + z; |
||||
} |
||||
void TestMethod () |
||||
{ |
||||
string ret; |
||||
string x; |
||||
int y; |
||||
NewMethod (out ret, x, y); |
||||
} |
||||
} |
||||
");
|
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Bug 616199 - Extract method forgets to return a local var which is used in main method
|
||||
/// </summary>
|
||||
[Ignore("FIXME!!")] |
||||
[Test()] |
||||
public void TestBug616199() |
||||
{ |
||||
Test<ExtractMethodAction>(@"class TestClass
|
||||
{ |
||||
void TestMethod () |
||||
{ |
||||
<-string z = ""test"" + ""x"";-> |
||||
string ret = ""test1"" + z; |
||||
} |
||||
} |
||||
", @"class TestClass |
||||
{ |
||||
static string NewMethod () |
||||
{ |
||||
string z = ""test"" + ""x""; |
||||
return z; |
||||
} |
||||
void TestMethod () |
||||
{ |
||||
string z = NewMethod (); |
||||
string ret = ""test1"" + z; |
||||
} |
||||
} |
||||
");
|
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Bug 666271 - "Extract Method" on single line adds two semi-colons in method, none in replaced text
|
||||
/// </summary>
|
||||
[Test()] |
||||
public void TestBug666271() |
||||
{ |
||||
Test<ExtractMethodAction>(@"class TestClass
|
||||
{ |
||||
void TestMethod () |
||||
{ |
||||
<-TestMethod ();-> |
||||
} |
||||
} |
||||
", @"class TestClass |
||||
{ |
||||
void NewMethod () |
||||
{ |
||||
TestMethod (); |
||||
} |
||||
void TestMethod () |
||||
{ |
||||
NewMethod (); |
||||
} |
||||
} |
||||
");
|
||||
} |
||||
|
||||
|
||||
/// <summary>
|
||||
/// Bug 693944 - Extracted method returns void instead of the correct type
|
||||
/// </summary>
|
||||
[Test()] |
||||
public void TestBug693944() |
||||
{ |
||||
Test<ExtractMethodAction>(@"class TestClass
|
||||
{ |
||||
void TestMethod () |
||||
{ |
||||
TestMethod (<-""Hello""->); |
||||
} |
||||
} |
||||
", @"class TestClass |
||||
{ |
||||
static string NewMethod () |
||||
{ |
||||
return ""Hello""; |
||||
} |
||||
void TestMethod () |
||||
{ |
||||
TestMethod (NewMethod ()); |
||||
} |
||||
} |
||||
");
|
||||
} |
||||
|
||||
|
||||
[Ignore("FIXME!!")] |
||||
[Test()] |
||||
public void ExtractMethodMultiVariableWithLocalReturnVariableTest() |
||||
{ |
||||
Test<ExtractMethodAction>(@"class TestClass
|
||||
{ |
||||
int member; |
||||
void TestMethod () |
||||
{ |
||||
int i = 5, j = 10, k; |
||||
<-int test; |
||||
j = i + j; |
||||
k = j + member; |
||||
test = i + j + k;-> |
||||
Console.WriteLine (test); |
||||
} |
||||
} |
||||
", @"class TestClass |
||||
{ |
||||
int member; |
||||
void NewMethod (ref int j, int i, out int k, out int test) |
||||
{ |
||||
j = i + j; |
||||
k = j + member; |
||||
test = i + j + k; |
||||
} |
||||
void TestMethod () |
||||
{ |
||||
int i = 5, j = 10, k; |
||||
int test; |
||||
NewMethod (i, ref j, out k, out test); |
||||
Console.WriteLine (test); |
||||
} |
||||
} |
||||
");
|
||||
} |
||||
} |
||||
} |
||||
|
||||
Loading…
Reference in new issue