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 @@ -382,6 +382,15 @@ internal static class Functions<T>
public static readonly Func<T, T> Identity = t => t;
public static readonly Func<T, bool> True = t => true;
}

/// <summary>
/// Cached versions of commonly used delegates.
/// </summary>
/// <typeparam name="T"></typeparam>
internal static class Predicates<T>
{
public static readonly Predicate<T> True = t => true;
}
}

namespace System.Linq
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.CodeRefactorings;
using Microsoft.CodeAnalysis.Test.Utilities;
using Roslyn.Test.Utilities;
using Xunit;

namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.CodeActions.ConvertLinq
Expand Down Expand Up @@ -4355,6 +4356,90 @@ IEnumerable<int> enumerable()
await TestInRegularAndScriptAsync(source, output, parseOptions: new CSharpParseOptions(CodeAnalysis.CSharp.LanguageVersion.CSharp8));
}

#endregion

#region CaretSelection
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsConvertQueryToForEach)]
[WorkItem(35180, "https://github.com/dotnet/roslyn/issues/35180")]
public async Task DeclarationSelection()
{
string source = @"
using System;
using System.Collections.Generic;
using System.Linq;
class Query
{
public static void Main(string[] args)
{
List<int> c = new List<int>{ 1, 2, 3, 4, 5, 6, 7 };
var r = [|from i in c select i+1;|]
}
}";
string output = @"
using System;
using System.Collections.Generic;
using System.Linq;
class Query
{
public static void Main(string[] args)
{
List<int> c = new List<int>{ 1, 2, 3, 4, 5, 6, 7 };
IEnumerable<int> enumerable()
{
foreach (var i in c)
{
yield return i + 1;
}
}

var r = enumerable();
}
}";
await TestInRegularAndScriptAsync(source, output);
}

[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsConvertQueryToForEach)]
[WorkItem(35180, "https://github.com/dotnet/roslyn/issues/35180")]
public async Task LocalAssignmentSelection()
{
string source = @"
using System;
using System.Collections.Generic;
using System.Linq;
class Query
{
public static void Main(string[] args)
{
List<int> c = new List<int>{ 1, 2, 3, 4, 5, 6, 7 };
IEnumerable<int> r;
[|r = from i in c select i+1;|]
}
}";
string output = @"
using System;
using System.Collections.Generic;
using System.Linq;
class Query
{
public static void Main(string[] args)
{
List<int> c = new List<int>{ 1, 2, 3, 4, 5, 6, 7 };
IEnumerable<int> r;
IEnumerable<int> enumerable()
{
foreach (var i in c)
{
yield return i + 1;
}
}

r = enumerable();
}
}";
await TestInRegularAndScriptAsync(source, output);
}


#endregion
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.CodeRefactorings;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.CodeRefactorings;
using Microsoft.CodeAnalysis.CSharp.CodeRefactorings.ConvertLocalFunctionToMethod;
using Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.CodeRefactorings;
using Microsoft.CodeAnalysis.Test.Utilities;
using Roslyn.Test.Utilities;
using Xunit;

namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.CodeActions.ConvertLocalFunctionToMethod
Expand Down Expand Up @@ -499,6 +500,7 @@ private static async void LocalFunction<T>(CancellationToken c, Task<T> task)
}

[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsConvertLocalFunctionToMethod)]
[WorkItem(35180, "https://github.com/dotnet/roslyn/issues/35180")]
public async Task TestCaretPositon()
{
await TestAsync("C [||]LocalFunction(C c)");
Expand Down Expand Up @@ -556,6 +558,7 @@ void M()
}

[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsConvertLocalFunctionToMethod)]
[WorkItem(35180, "https://github.com/dotnet/roslyn/issues/35180")]
public async Task TestMethodBlockSelection1()
{
await TestInRegularAndScriptAsync(
Expand Down Expand Up @@ -583,6 +586,7 @@ private static C LocalFunction(C c)
}

[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsConvertLocalFunctionToMethod)]
[WorkItem(35180, "https://github.com/dotnet/roslyn/issues/35180")]
public async Task TestMethodBlockSelection2()
{

Expand All @@ -600,6 +604,7 @@ C LocalFunction(C c)[|
}

[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsConvertLocalFunctionToMethod)]
[WorkItem(35180, "https://github.com/dotnet/roslyn/issues/35180")]
public async Task TestMethodBlockSelection3()
{
await TestInRegularAndScriptAsync(
Expand Down Expand Up @@ -631,6 +636,7 @@ private static C LocalFunction(C c)
}

[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsConvertLocalFunctionToMethod)]
[WorkItem(35180, "https://github.com/dotnet/roslyn/issues/35180")]
public async Task TestMethodBlockSelection4()
{

Expand All @@ -651,6 +657,7 @@ C LocalFunction(C c)
}

[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsConvertLocalFunctionToMethod)]
[WorkItem(35180, "https://github.com/dotnet/roslyn/issues/35180")]
public async Task TestMethodBlockSelection5()
{

Expand All @@ -672,6 +679,7 @@ C LocalFunction(C c)
}

[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsConvertLocalFunctionToMethod)]
[WorkItem(35180, "https://github.com/dotnet/roslyn/issues/35180")]
public async Task TestMethodBlockSelection6()
{

Expand All @@ -694,6 +702,7 @@ C LocalFunction(C c)
}

[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsConvertLocalFunctionToMethod)]
[WorkItem(35180, "https://github.com/dotnet/roslyn/issues/35180")]
public async Task TestMethodBlockSelection7()
{
await TestMissingAsync(
Expand All @@ -710,6 +719,7 @@ C LocalFunction(C c)
}

[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsConvertLocalFunctionToMethod)]
[WorkItem(35180, "https://github.com/dotnet/roslyn/issues/35180")]
public async Task TestMethodBlockSelection8()
{
await TestInRegularAndScriptAsync(
Expand Down Expand Up @@ -737,6 +747,7 @@ private static C LocalFunction(C c)
}

[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsConvertLocalFunctionToMethod)]
[WorkItem(35180, "https://github.com/dotnet/roslyn/issues/35180")]
public async Task TestMethodBlockSelection9()
{
await TestInRegularAndScriptAsync(
Expand Down Expand Up @@ -764,6 +775,7 @@ private static C LocalFunction(C c)
}

[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsConvertLocalFunctionToMethod)]
[WorkItem(35180, "https://github.com/dotnet/roslyn/issues/35180")]
public async Task TestMethodBlockSelection10()
{
await TestInRegularAndScriptAsync(
Expand All @@ -790,6 +802,7 @@ private static C LocalFunction(C c)
}");
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsConvertLocalFunctionToMethod)]
[WorkItem(35180, "https://github.com/dotnet/roslyn/issues/35180")]
public async Task TestMethodBlockSelection11()
{
await TestMissingAsync(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2266,5 +2266,104 @@ public override event EventHandler Event1
}

#endregion Dialog

#region Selections and caret position
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsPullMemberUp)]
[WorkItem(35180, "https://github.com/dotnet/roslyn/issues/35180")]
public async Task TestNoRefactoringCaretInArgs()
{
var input = @"
namespace PushUpTest
{
public class A
{

}

public class B : A
{
void C([||])
{

}
}
}";

await TestQuickActionNotProvidedAsync(input);
}

[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsPullMemberUp)]
[WorkItem(35180, "https://github.com/dotnet/roslyn/issues/35180")]
public async Task TestRefactoringCaretLoc1()
{
var testText = @"
namespace PushUpTest
{
public class A
{
}

public class B : A
{
[||]void C()
{
}
}
}";
var expected = @"
namespace PushUpTest
{
public class A
{
void C()
{
}
}

public class B : A
{
}
}";

await TestInRegularAndScriptAsync(testText, expected);
}

[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsPullMemberUp)]
[WorkItem(35180, "https://github.com/dotnet/roslyn/issues/35180")]
public async Task TestRefactoringSelection()
{
var testText = @"
namespace PushUpTest
{
public class A
{
}

public class B : A
{
[|void C()
{
}|]
}
}";
var expected = @"
namespace PushUpTest
{
public class A
{
void C()
{
}
}

public class B : A
{
}
}";

await TestInRegularAndScriptAsync(testText, expected);
}

#endregion
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

using System.Composition;
using Microsoft.CodeAnalysis.CodeRefactorings;
using Microsoft.CodeAnalysis.Host.Mef;

namespace Microsoft.CodeAnalysis.CSharp.CodeRefactorings
{
[ExportLanguageService(typeof(IRefactoringHelpersService), LanguageNames.CSharp), Shared]
internal class CSharpRefactoringHelpersService : AbstractRefactoringHelpersService
{
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
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 @@ -41,8 +40,9 @@ public override async Task ComputeRefactoringsAsync(CodeRefactoringContext conte
}

var cancellationToken = context.CancellationToken;
var refactoringHelperService = document.GetLanguageService<IRefactoringHelpersService>();

var localFunction = await CodeRefactoringHelpers.TryGetSelectedNodeAsync<LocalFunctionStatementSyntax>(document, context.Span, cancellationToken).ConfigureAwait(false);
var localFunction = await refactoringHelperService.TryGetSelectedNodeAsync<LocalFunctionStatementSyntax>(document, context.Span, cancellationToken).ConfigureAwait(false);
if (localFunction == default)
{
return;
Expand Down
Loading