Browse Source

Startet exctract method action.

newNRvisualizers
Mike Krüger 14 years ago
parent
commit
8444dffd81
  1. 7
      ICSharpCode.NRefactory.CSharp/Ast/TypeMembers/ParameterDeclaration.cs
  2. 4
      ICSharpCode.NRefactory.CSharp/ICSharpCode.NRefactory.CSharp.csproj
  3. 8
      ICSharpCode.NRefactory.CSharp/Refactoring/BaseRefactoringContext.cs
  4. 185
      ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/ExtractMethod/ExtractMethodAction.cs
  5. 85
      ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/ExtractMethod/StaticVisitor.cs
  6. 97
      ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/ExtractMethod/VariableLookupVisitor.cs
  7. 2
      ICSharpCode.NRefactory.CSharp/Refactoring/RefactoringContext.cs
  8. 373
      ICSharpCode.NRefactory.Tests/CSharp/CodeActions/ExtractMethodTests.cs
  9. 3
      ICSharpCode.NRefactory.Tests/ICSharpCode.NRefactory.Tests.csproj

7
ICSharpCode.NRefactory.CSharp/Ast/TypeMembers/ParameterDeclaration.cs

@ -121,10 +121,11 @@ namespace ICSharpCode.NRefactory.CSharp @@ -121,10 +121,11 @@ namespace ICSharpCode.NRefactory.CSharp
{
}
public ParameterDeclaration(AstType type, string name)
public ParameterDeclaration(AstType type, string name, ParameterModifier modifier = ParameterModifier.None)
{
this.Type = type;
this.Name = name;
Type = type;
Name = name;
ParameterModifier = modifier;
}
}
}

4
ICSharpCode.NRefactory.CSharp/ICSharpCode.NRefactory.CSharp.csproj

@ -359,6 +359,9 @@ @@ -359,6 +359,9 @@
<Compile Include="Refactoring\CodeActions\CreateDelegateAction.cs" />
<Compile Include="Formatter\TextEditorOptions.cs" />
<Compile Include="Refactoring\CodeActions\IntroduceConstantAction.cs" />
<Compile Include="Refactoring\CodeActions\ExtractMethod\ExtractMethodAction.cs" />
<Compile Include="Refactoring\CodeActions\ExtractMethod\StaticVisitor.cs" />
<Compile Include="Refactoring\CodeActions\ExtractMethod\VariableLookupVisitor.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\ICSharpCode.NRefactory\ICSharpCode.NRefactory.csproj">
@ -371,6 +374,7 @@ @@ -371,6 +374,7 @@
<Folder Include="Completion\" />
<Folder Include="Refactoring\CodeIssues\" />
<Folder Include="Refactoring\CodeIssues\InconsistentNamingIssue\" />
<Folder Include="Refactoring\CodeActions\ExtractMethod\" />
</ItemGroup>
<ProjectExtensions>
<MonoDevelop>

8
ICSharpCode.NRefactory.CSharp/Refactoring/BaseRefactoringContext.cs

@ -39,7 +39,7 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring @@ -39,7 +39,7 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring
{
public abstract class BaseRefactoringContext : IServiceProvider
{
protected readonly CSharpAstResolver resolver;
readonly CSharpAstResolver resolver;
readonly CancellationToken cancellationToken;
public virtual bool Supports(Version version)
@ -65,6 +65,12 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring @@ -65,6 +65,12 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring
}
}
public CSharpAstResolver Resolver {
get {
return resolver;
}
}
public virtual CSharpParsedFile ParsedFile {
get {
return resolver.ParsedFile;

185
ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/ExtractMethod/ExtractMethodAction.cs

@ -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);
});
}
}
}

85
ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/ExtractMethod/StaticVisitor.cs

@ -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;
}
}
}
}

97
ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/ExtractMethod/VariableLookupVisitor.cs

@ -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;
}
}
}

2
ICSharpCode.NRefactory.CSharp/Refactoring/RefactoringContext.cs

@ -47,7 +47,7 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring @@ -47,7 +47,7 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring
public virtual AstType CreateShortType (IType fullType)
{
var csResolver = resolver.GetResolverStateBefore(GetNode());
var csResolver = Resolver.GetResolverStateBefore(GetNode());
var builder = new TypeSystemAstBuilder(csResolver);
return builder.ConvertType(fullType);
}

373
ICSharpCode.NRefactory.Tests/CSharp/CodeActions/ExtractMethodTests.cs

@ -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);
}
}
");
}
}
}

3
ICSharpCode.NRefactory.Tests/ICSharpCode.NRefactory.Tests.csproj

@ -260,6 +260,7 @@ @@ -260,6 +260,7 @@
<Compile Include="CSharp\CodeActions\CreateConstructorDeclarationTests.cs" />
<Compile Include="CSharp\CodeActions\CreateDelegateTests.cs" />
<Compile Include="CSharp\CodeActions\IntroduceConstantTests.cs" />
<Compile Include="CSharp\CodeActions\ExtractMethodTests.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\Mono.Cecil\Mono.Cecil.csproj">
@ -294,6 +295,8 @@ @@ -294,6 +295,8 @@
<Properties>
<Policies>
<TextStylePolicy TabWidth="4" EolMarker="Unix" inheritsSet="Mono" inheritsScope="text/plain" scope="text/plain" />
<TextStylePolicy FileWidth="120" TabWidth="4" EolMarker="Unix" inheritsSet="Mono" inheritsScope="text/plain" scope="text/x-csharp" />
<CSharpFormattingPolicy inheritsSet="1TBS" inheritsScope="text/x-csharp" scope="text/x-csharp" />
</Policies>
</Properties>
</MonoDevelop>

Loading…
Cancel
Save