Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -505,10 +505,11 @@ public async Task TestCaretPositon()
await TestAsync("C Local[||]Function(C c)");
await TestAsync("C [|LocalFunction|](C c)");
await TestAsync("C LocalFunction[||](C c)");
await TestMissingAsync("C Local[|Function|](C c)");
await TestMissingAsync("[||]C LocalFunction(C c)");
await TestAsync("C Local[|Function|](C c)");
await TestAsync("[||]C LocalFunction(C c)");
await TestMissingAsync("[|C|] LocalFunction(C c)");
await TestMissingAsync("C[||] LocalFunction(C c)");
await TestMissingAsync("C[| |]LocalFunction(C c)");
await TestMissingAsync("C LocalFunction([||]C c)");
await TestMissingAsync("C LocalFunction(C [||]c)");

Expand Down Expand Up @@ -553,5 +554,256 @@ void M()
}}");
}
}

[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsConvertLocalFunctionToMethod)]
public async Task TestMethodBlockSelection1()
{
await TestInRegularAndScriptAsync(
@"class C
{
void M()
{
[|C LocalFunction(C c)
{
return null;
}|]
}
}",
@"class C
{
void M()
{
}

private static C LocalFunction(C c)
{
return null;
}
}");
}

[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsConvertLocalFunctionToMethod)]
public async Task TestMethodBlockSelection2()
{

await TestMissingAsync(
@"class C
{
void M()
{
C LocalFunction(C c)[|
{
return null;
}|]
}
}");
}

[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsConvertLocalFunctionToMethod)]
public async Task TestMethodBlockSelection3()
{
await TestInRegularAndScriptAsync(

@"class C
{
void M()
{
[|
C LocalFunction(C c)
{
return null;
}
|]
}
}",
@"class C
{
void M()
{

}

private static C LocalFunction(C c)
{
return null;
}
}");
}

[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsConvertLocalFunctionToMethod)]
public async Task TestMethodBlockSelection4()
{

await this.TestMissingAsync(
@"class C
{
void M()
{

object a = null[|;
C LocalFunction(C c)
{
return null;

}|]
}
}");
}

[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsConvertLocalFunctionToMethod)]
public async Task TestMethodBlockSelection5()
{

await this.TestMissingAsync(
@"class C
{
void M()
{

[|
C LocalFunction(C c)
{
return null;

}
object|] a = null
}
}");
}

[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsConvertLocalFunctionToMethod)]
public async Task TestMethodBlockSelection6()
{

await this.TestMissingAsync(
@"class C
{
void M()
{
C LocalFunction(C c)
{
object b = null;
[|
object a = null;
return null;
|]

}
}
}");
}

[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsConvertLocalFunctionToMethod)]
public async Task TestMethodBlockSelection7()
{
await TestMissingAsync(
@"class C
{
void M()
{
C LocalFunction(C c)
{
[|return null;|]
}
}
}");
}

[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsConvertLocalFunctionToMethod)]
public async Task TestMethodBlockSelection8()
{
await TestInRegularAndScriptAsync(
@"class C
{
void M()
{
[|C LocalFunction(C c)|]
{
return null;
}
}
}",
@"class C
{
void M()
{
}

private static C LocalFunction(C c)
{
return null;
}
}");
}

[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsConvertLocalFunctionToMethod)]
public async Task TestMethodBlockSelection9()
{
await TestInRegularAndScriptAsync(
@"class C
{
void M()
{
C LocalFunction(C c)
{
return null;
}[||]
}
}",
@"class C
{
void M()
{
}

private static C LocalFunction(C c)
{
return null;
}
}");
}

[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsConvertLocalFunctionToMethod)]
public async Task TestMethodBlockSelection10()
{
await TestInRegularAndScriptAsync(
@"class C
{
void M()
{
[||]C LocalFunction(C c)
{
return null;
}
}
}",
@"class C
{
void M()
{
}

private static C LocalFunction(C c)
{
return null;
}
}");
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsConvertLocalFunctionToMethod)]
public async Task TestMethodBlockSelection11()
{
await TestMissingAsync(
@"class C
{
void M()
{
object a = null;[||]
C LocalFunction(C c)
{
return null;
}
}
}");
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
using Microsoft.CodeAnalysis.Shared.Extensions;
using Microsoft.CodeAnalysis.Shared.Utilities;
using Microsoft.CodeAnalysis.Simplification;
using Microsoft.CodeAnalysis.Text;
using Roslyn.Utilities;

namespace Microsoft.CodeAnalysis.CSharp.CodeRefactorings.ConvertLocalFunctionToMethod
Expand All @@ -40,23 +41,9 @@ public override async Task ComputeRefactoringsAsync(CodeRefactoringContext conte
}

var cancellationToken = context.CancellationToken;
var root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);

var identifier = await root.SyntaxTree.GetTouchingTokenAsync(context.Span.Start,
token => token.Parent.IsKind(SyntaxKind.LocalFunctionStatement), cancellationToken).ConfigureAwait(false);
if (identifier == default)
{
return;
}

if (context.Span.Length > 0 &&
context.Span != identifier.Span)
{
return;
}

var localFunction = (LocalFunctionStatementSyntax)identifier.Parent;
if (localFunction.Identifier != identifier)
var localFunction = await CodeRefactoringHelpers.TryGetSelectedNodeAsync<LocalFunctionStatementSyntax>(document, context.Span, cancellationToken).ConfigureAwait(false);
if (localFunction == default)
{
return;
}
Expand All @@ -66,6 +53,8 @@ public override async Task ComputeRefactoringsAsync(CodeRefactoringContext conte
return;
}

var root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);

context.RegisterRefactoring(new MyCodeAction(CSharpFeaturesResources.Convert_to_method,
c => UpdateDocumentAsync(root, document, parentBlock, localFunction, c)));
}
Expand Down
Loading