Skip to content

Commit

Permalink
Fix UseLocalFunction when converting a single-line lambda. (dotnet#24773
Browse files Browse the repository at this point in the history
)

* Fix UseLocalFunction when converting a single-line lambda.

* Add more tests.
  • Loading branch information
CyrusNajmabadi authored and heejaechang committed Feb 13, 2018
1 parent f65b4c7 commit 0b63531
Show file tree
Hide file tree
Showing 3 changed files with 256 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -1239,8 +1239,7 @@ class Program
{
static void Main(string[] args)
{
Task f(string x)
{ return Task.CompletedTask; }
Task f(string x) { return Task.CompletedTask; }
Func<string, Task> actual = null;
AssertSame(f, actual);
}
Expand Down Expand Up @@ -1694,6 +1693,252 @@ public void Caller(T t)
local(t);
}
}
}");
}

[WorkItem(23872, "https://github.com/dotnet/roslyn/issues/23872")]
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseLocalFunction)]
public async Task TestSimpleInitialization_SingleLine1()
{
await TestInRegularAndScriptAsync(
@"using System;
class C
{
void Goo()
{
var buildCancelled = false;
Action [||]onUpdateSolutionCancel = () => { buildCancelled = true; };
}
}",
@"using System;
class C
{
void Goo()
{
var buildCancelled = false;
void onUpdateSolutionCancel() { buildCancelled = true; }
}
}");
}

[WorkItem(23872, "https://github.com/dotnet/roslyn/issues/23872")]
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseLocalFunction)]
public async Task TestSimpleInitialization_SingleLine2()
{
await TestInRegularAndScriptAsync(
@"using System;
class C
{
void Goo()
{
var buildCancelled = false;
Action<int> [||]onUpdateSolutionCancel = a => { buildCancelled = true; };
}
}",
@"using System;
class C
{
void Goo()
{
var buildCancelled = false;
void onUpdateSolutionCancel(int a) { buildCancelled = true; }
}
}");
}

[WorkItem(23872, "https://github.com/dotnet/roslyn/issues/23872")]
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseLocalFunction)]
public async Task TestSimpleInitialization_SingleLine3()
{
await TestInRegularAndScriptAsync(
@"using System;
class C
{
void Goo()
{
var buildCancelled = false;
Action<int> [||]onUpdateSolutionCancel = (int a) => { buildCancelled = true; };
}
}",
@"using System;
class C
{
void Goo()
{
var buildCancelled = false;
void onUpdateSolutionCancel(int a) { buildCancelled = true; }
}
}");
}

[WorkItem(23872, "https://github.com/dotnet/roslyn/issues/23872")]
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseLocalFunction)]
public async Task TestCastInitialization_SingleLine1()
{
await TestInRegularAndScriptAsync(
@"using System;
class C
{
void Goo()
{
var buildCancelled = false;
var [||]onUpdateSolutionCancel = (Action)(() => { buildCancelled = true; });
}
}",
@"using System;
class C
{
void Goo()
{
var buildCancelled = false;
void onUpdateSolutionCancel() { buildCancelled = true; }
}
}");
}

[WorkItem(23872, "https://github.com/dotnet/roslyn/issues/23872")]
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseLocalFunction)]
public async Task TestCastInitialization_SingleLine2()
{
await TestInRegularAndScriptAsync(
@"using System;
class C
{
void Goo()
{
var buildCancelled = false;
var [||]onUpdateSolutionCancel = (Action<int>)(a => { buildCancelled = true; });
}
}",
@"using System;
class C
{
void Goo()
{
var buildCancelled = false;
void onUpdateSolutionCancel(int a) { buildCancelled = true; }
}
}");
}

[WorkItem(23872, "https://github.com/dotnet/roslyn/issues/23872")]
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseLocalFunction)]
public async Task TestCastInitialization_SingleLine3()
{
await TestInRegularAndScriptAsync(
@"using System;
class C
{
void Goo()
{
var buildCancelled = false;
var [||]onUpdateSolutionCancel = (Action<int>)((int a) => { buildCancelled = true; });
}
}",
@"using System;
class C
{
void Goo()
{
var buildCancelled = false;
void onUpdateSolutionCancel(int a) { buildCancelled = true; }
}
}");
}

[WorkItem(23872, "https://github.com/dotnet/roslyn/issues/23872")]
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseLocalFunction)]
public async Task TestSplitInitialization_SingleLine1()
{
await TestInRegularAndScriptAsync(
@"using System;
class C
{
void Goo()
{
var buildCancelled = false;
Action [||]onUpdateSolutionCancel = null;
onUpdateSolutionCancel = () => { buildCancelled = true; };
}
}",
@"using System;
class C
{
void Goo()
{
var buildCancelled = false;
void onUpdateSolutionCancel() { buildCancelled = true; }
}
}");
}

[WorkItem(23872, "https://github.com/dotnet/roslyn/issues/23872")]
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseLocalFunction)]
public async Task TestSplitInitialization_SingleLine2()
{
await TestInRegularAndScriptAsync(
@"using System;
class C
{
void Goo()
{
var buildCancelled = false;
Action<int> [||]onUpdateSolutionCancel = null;
onUpdateSolutionCancel = a => { buildCancelled = true; };
}
}",
@"using System;
class C
{
void Goo()
{
var buildCancelled = false;
void onUpdateSolutionCancel(int a) { buildCancelled = true; }
}
}");
}

[WorkItem(23872, "https://github.com/dotnet/roslyn/issues/23872")]
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseLocalFunction)]
public async Task TestSplitInitialization_SingleLine3()
{
await TestInRegularAndScriptAsync(
@"using System;
class C
{
void Goo()
{
var buildCancelled = false;
Action<int> [||]onUpdateSolutionCancel = null;
onUpdateSolutionCancel = (int a) => { buildCancelled = true; };
}
}",
@"using System;
class C
{
void Goo()
{
var buildCancelled = false;
void onUpdateSolutionCancel(int a) { buildCancelled = true; }
}
}");
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -135,8 +135,12 @@ private LocalFunctionStatementSyntax CreateLocalFunctionStatement(
: default;

var invokeMethod = delegateType.DelegateInvokeMethod;
var returnType = invokeMethod.GenerateReturnTypeSyntax();

// We add a space directly after the return-type, as the default presence of an elastic
// trivia makes the formatting engine thing it can take a single-line local function and
// wrap it over multiple lines.
var returnType = invokeMethod.GenerateReturnTypeSyntax().WithTrailingTrivia(SyntaxFactory.Space);

var identifier = localDeclaration.Declaration.Variables[0].Identifier;
var typeParameterList = default(TypeParameterListSyntax);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -124,9 +124,11 @@ private void AddSpecificNodesSuppressOperations(List<SuppressOperation> list, Sy
}
}

if (node is AnonymousMethodExpressionSyntax anonymousMethod)
if (node is AnonymousFunctionExpressionSyntax ||
node is LocalFunctionStatementSyntax)
{
AddSuppressWrappingIfOnSingleLineOperation(list, anonymousMethod.DelegateKeyword, anonymousMethod.GetLastToken(includeZeroWidth: true));
AddSuppressWrappingIfOnSingleLineOperation(
list, node.GetFirstToken(includeZeroWidth: true), node.GetLastToken(includeZeroWidth: true));
return;
}

Expand Down

0 comments on commit 0b63531

Please sign in to comment.