/
githubmirror
/
roslyn
Обзор
Документация
Войти
/
githubmirror
/
roslyn
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
src/EditorFeatures/CSharpTest/CodeActions/InlineMethod/CSharpInlineMethodTests.cs
3 968 строк
112 KB
Jason Malinowski
Switch code that was using Assert.True/False as a replacement for .Fail
21 апр 2026, 23:28
21 апр 2026, 23:28
3bf59ba
Код
Авторство
О чём код?
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. #nullable disable using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using System.Threading.Tasks; using Microsoft.CodeAnalysis.CSharp.CodeRefactorings.InlineMethod; using Microsoft.CodeAnalysis.Editor.UnitTests.CodeActions; using Microsoft.CodeAnalysis.Test.Utilities; using Microsoft.CodeAnalysis.Testing; using Roslyn.Test.Utilities; using Xunit; namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.InlineMethod; [UseExportProvider] [Trait(Traits.Feature, Traits.Features.CodeActionsInlineMethod)] public sealed class CSharpInlineMethodTests { private sealed class TestVerifier : CSharpCodeRefactoringVerifier<CSharpInlineMethodRefactoringProvider>.Test { private const string Marker = "##"; public static async Task TestInRegularScriptsInDifferentFilesAsync( [StringSyntax(PredefinedEmbeddedLanguageNames.CSharpTest)] string initialMarkUpForFile1, [StringSyntax(PredefinedEmbeddedLanguageNames.CSharpTest)] string initialMarkUpForFile2, [StringSyntax(PredefinedEmbeddedLanguageNames.CSharpTest)] string expectedMarkUpForFile1, [StringSyntax(PredefinedEmbeddedLanguageNames.CSharpTest)] string expectedMarkUpForFile2, List<DiagnosticResult> diagnosticResults = null, bool keepInlinedMethod = true) { diagnosticResults ??= []; var test = new TestVerifier { CodeActionIndex = keepInlinedMethod ? 1 : 0, TestState = { Sources = { ("File1", initialMarkUpForFile1), ("File2", initialMarkUpForFile2), } }, FixedState = { Sources = { ("File1", expectedMarkUpForFile1), ("File2", expectedMarkUpForFile2), } }, CodeActionValidationMode = CodeActionValidationMode.None, LanguageVersion = CodeAnalysis.CSharp.LanguageVersion.CSharp9, }; test.FixedState.ExpectedDiagnostics.AddRange(diagnosticResults); await test.RunAsync().ConfigureAwait(false); } public static async Task TestInRegularAndScriptInTheSameFileAsync( [StringSyntax(PredefinedEmbeddedLanguageNames.CSharpTest)] string initialMarkUp, [StringSyntax(PredefinedEmbeddedLanguageNames.CSharpTest)] string expectedMarkUp, List<DiagnosticResult> diagnosticResults = null, bool keepInlinedMethod = true) { diagnosticResults ??= []; var test = new TestVerifier { CodeActionIndex = keepInlinedMethod ? 1 : 0, TestState = { Sources = { initialMarkUp } }, FixedState = { Sources = { expectedMarkUp }, }, CodeActionValidationMode = CodeActionValidationMode.None, LanguageVersion = CodeAnalysis.CSharp.LanguageVersion.CSharp9, }; test.FixedState.ExpectedDiagnostics.AddRange(diagnosticResults); await test.RunAsync().ConfigureAwait(false); } public static async Task TestBothKeepAndRemoveInlinedMethodInDifferentFileAsync( [StringSyntax(PredefinedEmbeddedLanguageNames.CSharpTest)] string initialMarkUpForCaller, [StringSyntax(PredefinedEmbeddedLanguageNames.CSharpTest)] string initialMarkUpForCallee, [StringSyntax(PredefinedEmbeddedLanguageNames.CSharpTest)] string expectedMarkUpForCaller, [StringSyntax(PredefinedEmbeddedLanguageNames.CSharpTest)] string expectedMarkUpForCallee, List<DiagnosticResult> diagnosticResultsWhenKeepInlinedMethod = null, List<DiagnosticResult> diagnosticResultsWhenRemoveInlinedMethod = null) { var firstMarkerIndex = expectedMarkUpForCallee.IndexOf(Marker); var secondMarkerIndex = expectedMarkUpForCallee.LastIndexOf(Marker); if (firstMarkerIndex == -1 || secondMarkerIndex == -1 || firstMarkerIndex == secondMarkerIndex) { Assert.Fail("Can't find proper marks that contains inlined method."); } var firstPartitionBeforeMarkUp = expectedMarkUpForCallee[..firstMarkerIndex]; var inlinedMethod = expectedMarkUpForCallee.Substring(firstMarkerIndex + 2, secondMarkerIndex - firstMarkerIndex - 2); var lastPartitionAfterMarkup = expectedMarkUpForCallee[(secondMarkerIndex + 2)..]; await TestInRegularScriptsInDifferentFilesAsync( initialMarkUpForCaller, initialMarkUpForCallee, expectedMarkUpForCaller, string.Concat(firstPartitionBeforeMarkUp, inlinedMethod, lastPartitionAfterMarkup), diagnosticResultsWhenKeepInlinedMethod, keepInlinedMethod: true).ConfigureAwait(false); await TestInRegularScriptsInDifferentFilesAsync( initialMarkUpForCaller, initialMarkUpForCallee, expectedMarkUpForCaller, string.Concat(firstPartitionBeforeMarkUp, lastPartitionAfterMarkup), diagnosticResultsWhenRemoveInlinedMethod, keepInlinedMethod: false).ConfigureAwait(false); } public static async Task TestBothKeepAndRemoveInlinedMethodInSameFileAsync( [StringSyntax(PredefinedEmbeddedLanguageNames.CSharpTest)] string initialMarkUp, [StringSyntax(PredefinedEmbeddedLanguageNames.CSharpTest)] string expectedMarkUp, List<DiagnosticResult> diagnosticResultsWhenKeepInlinedMethod = null, List<DiagnosticResult> diagnosticResultsWhenRemoveInlinedMethod = null) { var firstMarkerIndex = expectedMarkUp.IndexOf(Marker); var secondMarkerIndex = expectedMarkUp.LastIndexOf(Marker); if (firstMarkerIndex == -1 || secondMarkerIndex == -1 || firstMarkerIndex == secondMarkerIndex) { Assert.Fail("Can't find proper marks that contains inlined method."); } var firstPartitionBeforeMarkUp = expectedMarkUp[..firstMarkerIndex]; var inlinedMethod = expectedMarkUp.Substring(firstMarkerIndex + 2, secondMarkerIndex - firstMarkerIndex - 2); var lastPartitionAfterMarkup = expectedMarkUp[(secondMarkerIndex + 2)..]; await TestInRegularAndScriptInTheSameFileAsync( initialMarkUp, string.Concat( firstPartitionBeforeMarkUp, inlinedMethod, lastPartitionAfterMarkup), diagnosticResultsWhenKeepInlinedMethod, keepInlinedMethod: true).ConfigureAwait(false); await TestInRegularAndScriptInTheSameFileAsync( initialMarkUp, string.Concat( firstPartitionBeforeMarkUp, lastPartitionAfterMarkup), diagnosticResultsWhenRemoveInlinedMethod, keepInlinedMethod: false).ConfigureAwait(false); } } [Fact] public Task TestInlineInvocationExpressionForExpressionStatement() => TestVerifier.TestBothKeepAndRemoveInlinedMethodInSameFileAsync( """ using System.Collections.Generic; public class TestClass { private void Caller(int i) { var h = new HashSet<int>(); Ca[||]llee(i, h); } private bool Callee(int i, HashSet<int> set) { return set.Add(i); } } """, """ using System.Collections.Generic; public class TestClass { private void Caller(int i) { var h = new HashSet<int>(); h.Add(i); } ## private bool Callee(int i, HashSet<int> set) { return set.Add(i); } ##} """); [Fact] public Task TestInlineMethodWithSingleStatement() => TestVerifier.TestBothKeepAndRemoveInlinedMethodInSameFileAsync( """ public class TestClass { private void Caller(int i, int j) { Ca[||]llee(i, j); } private void Callee(int i, int j) { System.Console.WriteLine(i + j); } } """, """ public class TestClass { private void Caller(int i, int j) { System.Console.WriteLine(i + j); } ## private void Callee(int i, int j) { System.Console.WriteLine(i + j); } ##} """); [Fact] public Task TestInlineMethodWithSingleStatementAcrossFile() => TestVerifier.TestBothKeepAndRemoveInlinedMethodInDifferentFileAsync( """ public partial class TestClass { private void Caller(int i, int j) { Ca[||]llee(i, j); } } """, """ public partial class TestClass { private void Callee(int i, int j) { System.Console.WriteLine(i + j); } } """, """ public partial class TestClass { private void Caller(int i, int j) { System.Console.WriteLine(i + j); } } """, """ public partial class TestClass {## private void Callee(int i, int j) { System.Console.WriteLine(i + j); }## } """); [Fact] public Task TestExtractArrowExpressionBody() => TestVerifier.TestBothKeepAndRemoveInlinedMethodInSameFileAsync(""" public class TestClass { private void Caller(int i, int j) { Ca[||]llee(i, j); } private void Callee(int i, int j) => System.Console.WriteLine(i + j); } """, """ public class TestClass { private void Caller(int i, int j) { System.Console.WriteLine(i + j); } ## private void Callee(int i, int j) => System.Console.WriteLine(i + j); ##} """); [Fact] public Task TestExtractArrowExpressionBodyAcrossFile() => TestVerifier.TestBothKeepAndRemoveInlinedMethodInDifferentFileAsync( """ public partial class TestClass { private void Caller(int i, int j) { Ca[||]llee(i, j); } } """, """ public partial class TestClass { private void Callee(int i, int j) => System.Console.WriteLine(i + j); } """, """ public partial class TestClass { private void Caller(int i, int j) { System.Console.WriteLine(i + j); } } """, """ public partial class TestClass {## private void Callee(int i, int j) => System.Console.WriteLine(i + j);## } """); [Fact] public Task TestExtractExpressionBody() => TestVerifier.TestBothKeepAndRemoveInlinedMethodInSameFileAsync( """ public class TestClass { private const int i = 10; private const int j = 20; private int X = Cal[||]lee(i, j); private static int Callee(int i, int j) => i + j; } """, """ public class TestClass { private const int i = 10; private const int j = 20; private int X = i + j; ## private static int Callee(int i, int j) => i + j; ##} """); [Fact] public Task TestDefaultValueReplacementForExpressionStatement() => TestVerifier.TestBothKeepAndRemoveInlinedMethodInSameFileAsync( """ public class TestClass { private TestClass() { Cal[||]lee(); } private void Callee(int i = 1, string c = null, bool y = false) { System.Console.WriteLine(y ? i : (c ?? "Hello").Length); } } """, """ public class TestClass { private TestClass() { System.Console.WriteLine(false ? 1 : (null ?? "Hello").Length); } ## private void Callee(int i = 1, string c = null, bool y = false) { System.Console.WriteLine(y ? i : (c ?? "Hello").Length); } ##} """); [Fact] public Task TestDefaultValueReplacementForExpressionStatementAcrossFile() => TestVerifier.TestBothKeepAndRemoveInlinedMethodInDifferentFileAsync( """ public partial class TestClass { private void Caller() { Cal[||]lee(); } } """, """ public partial class TestClass { private void Callee(int i = 1, string c = null, bool y = false) { System.Console.WriteLine(y ? i : (c ?? "Hello").Length); } } """, """ public partial class TestClass { private void Caller() { System.Console.WriteLine(false ? 1 : (null ?? "Hello").Length); } } """, """ public partial class TestClass {## private void Callee(int i = 1, string c = null, bool y = false) { System.Console.WriteLine(y ? i : (c ?? "Hello").Length); }## } """); [Fact] public Task TestDefaultValueReplacementForArrowExpression() => TestVerifier.TestBothKeepAndRemoveInlinedMethodInSameFileAsync( """ public enum A { Value1, Value2 } public class TestClass { private void Caller() { Cal[||]lee(); } private void Callee(int i = default, string c = default, bool y = false, A a = default) => System.Console.WriteLine((y ? i : (c ?? "Hello").Length) + (int)a); } """, """ public enum A { Value1, Value2 } public class TestClass { private void Caller() { System.Console.WriteLine((false ? 0 : (null ?? "Hello").Length) + (int)A.Value1); } ## private void Callee(int i = default, string c = default, bool y = false, A a = default) => System.Console.WriteLine((y ? i : (c ?? "Hello").Length) + (int)a); ##} """); [Fact] public Task TestInlineMethodWithLiteralValue() => TestVerifier.TestBothKeepAndRemoveInlinedMethodInSameFileAsync( """ using System; public enum A { Value1, Value2 } public class TestClass { event EventHandler E { add { Cal[||]lee(1, 'y', true, "Hello", A.Value2); } remove {} } private void Callee(int i, char c, bool x, string y, A a) => System.Console.WriteLine(i + (int)c + (int)a + (x ? 1 : y.Length)); } """, """ using System; public enum A { Value1, Value2 } public class TestClass { event EventHandler E { add { System.Console.WriteLine(1 + (int)'y' + (int)A.Value2 + (true ? 1 : "Hello".Length)); } remove {} } ## private void Callee(int i, char c, bool x, string y, A a) => System.Console.WriteLine(i + (int)c + (int)a + (x ? 1 : y.Length)); ##} """); [Fact] public Task TestInlineMethodWithLiteralValueAcrossFile() => TestVerifier.TestBothKeepAndRemoveInlinedMethodInDifferentFileAsync( """ public partial class TestClass { private void Caller() { Cal[||]lee(1, 'y', true, "Hello"); } } """, """ public partial class TestClass { private void Callee(int i, char c, bool x, string y) => System.Console.WriteLine(i + (int)c + (x ? 1 : y.Length)); } """, """ public partial class TestClass { private void Caller() { System.Console.WriteLine(1 + (int)'y' + (true ? 1 : "Hello".Length)); } } """, """ public partial class TestClass {## private void Callee(int i, char c, bool x, string y) => System.Console.WriteLine(i + (int)c + (x ? 1 : y.Length));## } """); [Fact] public Task TestInlineMethodWithIdentifierReplacement() => TestVerifier.TestBothKeepAndRemoveInlinedMethodInSameFileAsync( """ public class TestClass { private void Caller(int m) { Cal[||]lee(10, m, k: "Hello"); } private void Callee(int i, int j = 100, string k = null) { System.Console.WriteLine(i + j + (k ?? "")); } } """, """ public class TestClass { private void Caller(int m) { System.Console.WriteLine(10 + m + ("Hello" ?? "")); } ## private void Callee(int i, int j = 100, string k = null) { System.Console.WriteLine(i + j + (k ?? "")); } ##} """); [Fact] public Task TestInlineMethodWithIdentifierReplacementAcrossFile() => TestVerifier.TestBothKeepAndRemoveInlinedMethodInDifferentFileAsync( """ public partial class TestClass { private void Caller(int m) { Cal[||]lee(10, m, k: "Hello"); } } """, """ public partial class TestClass { private void Callee(int i, int j = 100, string k = null) { System.Console.WriteLine(i + j + (k ?? "")); } } """, """ public partial class TestClass { private void Caller(int m) { System.Console.WriteLine(10 + m + ("Hello" ?? "")); } } """, """ public partial class TestClass {## private void Callee(int i, int j = 100, string k = null) { System.Console.WriteLine(i + j + (k ?? "")); }## } """); [Fact] public Task TestInlineMethodWithNoMethodExtraction() => TestVerifier.TestBothKeepAndRemoveInlinedMethodInSameFileAsync( """ public class TestClass { private void Caller(float r1, float r2) { Cal[||]lee(SomeCaculation(r1), SomeCaculation(r2)); } private void Callee(float s1, float s2) { System.Console.WriteLine("This is s1" + s1 + "This is S2" + s2); } public float SomeCaculation(float r) { return r * r * 3.14f; } } """, """ public class TestClass { private void Caller(float r1, float r2) { System.Console.WriteLine("This is s1" + SomeCaculation(r1) + "This is S2" + SomeCaculation(r2)); } ## private void Callee(float s1, float s2) { System.Console.WriteLine("This is s1" + s1 + "This is S2" + s2); } ## public float SomeCaculation(float r) { return r * r * 3.14f; } } """); [Fact] public Task TestInlineMethodWithNoMethodExtractionAcrossFile() => TestVerifier.TestBothKeepAndRemoveInlinedMethodInDifferentFileAsync( """ public partial class TestClass { public void Caller(float r1, float r2) { Cal[||]lee(SomeCaculation(r1), SomeCaculation(r2)); } public float SomeCaculation(float r) { return r * r * 3.14f; } } """, """ public partial class TestClass { private void Callee(float s1, float s2) { System.Console.WriteLine("This is s1" + s1 + "This is S2" + s2); } } """, """ public partial class TestClass { public void Caller(float r1, float r2) { System.Console.WriteLine("This is s1" + SomeCaculation(r1) + "This is S2" + SomeCaculation(r2)); } public float SomeCaculation(float r) { return r * r * 3.14f; } } """, """ public partial class TestClass {## private void Callee(float s1, float s2) { System.Console.WriteLine("This is s1" + s1 + "This is S2" + s2); }## } """); [Fact] public Task TestInlineParamsArrayWithArrayImplicitInitializerExpression() => TestVerifier.TestBothKeepAndRemoveInlinedMethodInSameFileAsync(""" public class TestClass { private void Caller() { Cal[||]lee(new int[] {1, 2, 3, 4, 5, 6}); } private void Callee(params int[] x) { System.Console.WriteLine(x.Length); } } """ , """ public class TestClass { private void Caller() { System.Console.WriteLine((new int[] {1, 2, 3, 4, 5, 6}).Length); } ## private void Callee(params int[] x) { System.Console.WriteLine(x.Length); } ##} """); [Fact] public Task TestInlineParamsArrayWithArrayImplicitInitializerExpressionAcrossFile() => TestVerifier.TestBothKeepAndRemoveInlinedMethodInDifferentFileAsync( """ public partial class TestClass { private void Caller() { Cal[||]lee(new int[] {1, 2, 3, 4, 5, 6}); } } """, """ public partial class TestClass { private void Callee(params int[] x) { System.Console.WriteLine(x.Length); } } """, """ public partial class TestClass { private void Caller() { System.Console.WriteLine((new int[] {1, 2, 3, 4, 5, 6}).Length); } } """, """ public partial class TestClass {## private void Callee(params int[] x) { System.Console.WriteLine(x.Length); }## } """); [Fact] public Task TestInlineParamsArrayWithArrayInitializerExpression() => TestVerifier.TestBothKeepAndRemoveInlinedMethodInSameFileAsync(""" public class TestClass { private void Caller() { Cal[||]lee(new int[6] {1, 2, 3, 4, 5, 6}); } private void Callee(params int[] x) { System.Console.WriteLine(x.Length); } } """ , """ public class TestClass { private void Caller() { System.Console.WriteLine((new int[6] {1, 2, 3, 4, 5, 6}).Length); } ## private void Callee(params int[] x) { System.Console.WriteLine(x.Length); } ##} """); [Fact] public Task TestInlineParamsArrayWithArrayInitializerExpressionAcrossFile() => TestVerifier.TestBothKeepAndRemoveInlinedMethodInDifferentFileAsync( """ public partial class TestClass { private void Caller() { Cal[||]lee(new int[6] {1, 2, 3, 4, 5, 6}); } } """, """ public partial class TestClass { private void Callee(params int[] x) { System.Console.WriteLine(x.Length); } } """, """ public partial class TestClass { private void Caller() { System.Console.WriteLine((new int[6] {1, 2, 3, 4, 5, 6}).Length); } } """, """ public partial class TestClass {## private void Callee(params int[] x) { System.Console.WriteLine(x.Length); }## } """); [Fact] public Task TestInlineParamsArrayWithOneElement() => TestVerifier.TestBothKeepAndRemoveInlinedMethodInSameFileAsync(""" public class TestClass { private void Caller() { Cal[||]lee(1); } private void Callee(params int[] x) { System.Console.WriteLine(x.Length); } } """ , """ public class TestClass { private void Caller() { System.Console.WriteLine((new int[] { 1 }).Length); } ## private void Callee(params int[] x) { System.Console.WriteLine(x.Length); } ##} """); [Fact] public Task TestInlineParamsArrayWithOneElementAcrossFile() => TestVerifier.TestBothKeepAndRemoveInlinedMethodInDifferentFileAsync( """ public partial class TestClass { private void Caller() { Cal[||]lee(1); } } """, """ public partial class TestClass { private void Callee(params int[] x) { System.Console.WriteLine(x.Length); } } """, """ public partial class TestClass { private void Caller() { System.Console.WriteLine((new int[] { 1 }).Length); } } """, """ public partial class TestClass {## private void Callee(params int[] x) { System.Console.WriteLine(x.Length); }## } """); [Fact] public Task TestInlineParamsArrayMethodWithIdentifier() => TestVerifier.TestBothKeepAndRemoveInlinedMethodInSameFileAsync(""" public class TestClass { private void Caller() { var i = new int[] {1, 2, 3, 4, 5}; Cal[||]lee(i); } private void Callee(params int[] x) { System.Console.WriteLine(x.Length); } } """, """ public class TestClass { private void Caller() { var i = new int[] {1, 2, 3, 4, 5}; System.Console.WriteLine(i.Length); } ## private void Callee(params int[] x) { System.Console.WriteLine(x.Length); } ##} """); [Fact] public Task TestInlineMethodWithNoElementInParamsArray() => TestVerifier.TestBothKeepAndRemoveInlinedMethodInSameFileAsync( """ public class TestClass { private void Caller() { Cal[||]lee(); } private void Callee(params int[] x) { System.Console.WriteLine(x.Length); } } """, """ public class TestClass { private void Caller() { System.Console.WriteLine((new int[] { }).Length); } ## private void Callee(params int[] x) { System.Console.WriteLine(x.Length); } ##} """); [Fact] public Task TestInlineMethodWithParamsArray() => TestVerifier.TestBothKeepAndRemoveInlinedMethodInSameFileAsync( """ public class TestClass { private void Caller() { Ca[||]llee("Hello", 1, 2, 3, 4, 5, 6); } private void Callee(string z, params int[] x) { System.Console.WriteLine(x.Length); } } """, """ public class TestClass { private void Caller() { System.Console.WriteLine((new int[] { 1, 2, 3, 4, 5, 6 }).Length); } ## private void Callee(string z, params int[] x) { System.Console.WriteLine(x.Length); } ##} """); [Fact] public Task TestInlineMethodWithVariableDeclaration1() => TestVerifier.TestBothKeepAndRemoveInlinedMethodInSameFileAsync( """ public class TestClass { private void Caller() { Cal[||]lee(out var x); } private void Callee(out int z) { z = 10; } } """, """ public class TestClass { private void Caller() { int x = 10; } ## private void Callee(out int z) { z = 10; } ##} """); [Fact] public Task TestInlineMethodWithVariableDeclaration1AcrossFile() => TestVerifier.TestBothKeepAndRemoveInlinedMethodInDifferentFileAsync( """ public partial class TestClass { private void Caller() { Cal[||]lee(out var x); } } """, """ public partial class TestClass { private void Callee(out int z) { z = 10; } } """, """ public partial class TestClass { private void Caller() { int x = 10; } } """, """ public partial class TestClass {## private void Callee(out int z) { z = 10; }## } """); [Fact] public Task TestInlineMethodWithVariableDeclaration2() => TestVerifier.TestBothKeepAndRemoveInlinedMethodInSameFileAsync( """ public class TestClass { private void Caller() { Cal[||]lee(out var x, out var y, out var z); } private void Callee(out int z, out int x, out int y) { z = x = y = 10; } } """, """ public class TestClass { private void Caller() { int x; int y; int z; x = y = z = 10; } ## private void Callee(out int z, out int x, out int y) { z = x = y = 10; } ##} """); [Fact] public Task TestInlineMethodWithVariableDeclaration2AcrossFile() => TestVerifier.TestBothKeepAndRemoveInlinedMethodInDifferentFileAsync( """ public partial class TestClass { private void Caller() { Cal[||]lee(out var x, out var y, out var z); } } """, """ public partial class TestClass { private void Callee(out int z, out int x, out int y) { z = x = y = 10; } } """, """ public partial class TestClass { private void Caller() { int x; int y; int z; x = y = z = 10; } } """, """ public partial class TestClass {## private void Callee(out int z, out int x, out int y) { z = x = y = 10; }## } """); [Fact] public Task TestInlineMethodWithVariableDeclaration3() => TestVerifier.TestBothKeepAndRemoveInlinedMethodInSameFileAsync( """ public class TestClass { private void Caller() { Cal[||]lee(out var x); } private void Callee(out int z) { DoSometing(out z); } private void DoSometing(out int z) { z = 100; } } """, """ public class TestClass { private void Caller() { int x; DoSometing(out x); } ## private void Callee(out int z) { DoSometing(out z); } ## private void DoSometing(out int z) { z = 100; } } """); [Fact] public Task TestInlineMethodWithVariableDeclaration3AcrossFile() => TestVerifier.TestBothKeepAndRemoveInlinedMethodInDifferentFileAsync( """ public partial class TestClass { private void Caller() { Cal[||]lee(out var x); } private void DoSometing(out int z) { z = 100; } } """, """ public partial class TestClass { private void Callee(out int z) { DoSometing(out z); } } """, """ public partial class TestClass { private void Caller() { int x; DoSometing(out x); } private void DoSometing(out int z) { z = 100; } } """, """ public partial class TestClass {## private void Callee(out int z) { DoSometing(out z); }## } """); [Fact] public Task TestInlineCalleeSelf() => TestVerifier.TestInRegularAndScriptInTheSameFileAsync( """ public class TestClass { public TestClass() { var x = Callee1(Cal[||]lee1(Callee1(Callee1(10)))); } private int Callee1(int j) { return 1 + 2 + j; } } """, """ public class TestClass { public TestClass() { var x = Callee1(1 + 2 + Callee1(Callee1(10))); } private int Callee1(int j) { return 1 + 2 + j; } } """); [Fact] public Task TestInlineMethodWithConditionalExpression() => TestVerifier.TestInRegularAndScriptInTheSameFileAsync( """ public class TestClass { public void Caller(bool x) { int t = C[||]allee(x ? Callee(1) : Callee(2)); } private int Callee(int i) { return i + 1; } } """, """ public class TestClass { public void Caller(bool x) { int t = (x ? Callee(1) : Callee(2)) + 1; } private int Callee(int i) { return i + 1; } } """); [Fact] public Task TestInlineExpressionWithoutAssignedToVariable() => TestVerifier.TestBothKeepAndRemoveInlinedMethodInSameFileAsync(""" public class TestClass { public void Caller(int j) { Cal[||]lee(j); } private int Callee(int i) { return i + 1; } } """, """ public class TestClass { public void Caller(int j) { int temp = j + 1; } ## private int Callee(int i) { return i + 1; } ##} """); [Fact] public Task TestInlineExpressionWithoutAssignedToVariableAcrossFile() => TestVerifier.TestBothKeepAndRemoveInlinedMethodInDifferentFileAsync( """ public partial class TestClass { public void Caller(int j) { Cal[||]lee(j); } } """, """ public partial class TestClass { private int Callee(int i) { return i + 1; } } """, """ public partial class TestClass { public void Caller(int j) { int temp = j + 1; } } """, """ public partial class TestClass {## private int Callee(int i) { return i + 1; }## } """); [Fact] public Task TestInlineMethodWithNullCoalescingExpression() => TestVerifier.TestBothKeepAndRemoveInlinedMethodInSameFileAsync(""" public class TestClass { public void Caller(int? i) { var t = Cal[||]lee(i ?? 1); } private int Callee(int i) { return i + 1; } } """, """ public class TestClass { public void Caller(int? i) { var t = (i ?? 1) + 1; } ## private int Callee(int i) { return i + 1; } ##} """); [Fact] public Task TestInlineSimpleLambdaExpression() => TestVerifier.TestBothKeepAndRemoveInlinedMethodInSameFileAsync(""" public class TestClass { public System.Func<int, int, int> Caller() { return Ca[||]llee(); } private System.Func<int, int, int> Callee() => (i, j) => i + j; } """, """ public class TestClass { public System.Func<int, int, int> Caller() { return (i, j) => i + j; } ## private System.Func<int, int, int> Callee() => (i, j) => i + j; ##} """); [Fact] public Task TestInlineSimpleLambdaExpressionAcrossFile() => TestVerifier.TestBothKeepAndRemoveInlinedMethodInDifferentFileAsync( """ public partial class TestClass { public System.Func<int, int, int> Caller() { return Ca[||]llee(); } } """, """ public partial class TestClass { private System.Func<int, int, int> Callee() => (i, j) => i + j; } """, """ public partial class TestClass { public System.Func<int, int, int> Caller() { return (i, j) => i + j; } } """, """ public partial class TestClass {## private System.Func<int, int, int> Callee() => (i, j) => i + j;## } """); [Fact] public Task TestInlineMethodWithGenericsArguments() => TestVerifier.TestBothKeepAndRemoveInlinedMethodInSameFileAsync( """ using System; public class TestClass { private void Caller<U>() { Ca[||]llee<int, U>(1, 2, 3); } private void Callee<T, U>(params T[] i) { System.Console.WriteLine(typeof(T).Name.Length + i.Length + typeof(U).Name.Length); } } """, """ using System; public class TestClass { private void Caller<U>() { System.Console.WriteLine(typeof(int).Name.Length + (new int[] { 1, 2, 3 }).Length + typeof(U).Name.Length); } ## private void Callee<T, U>(params T[] i) { System.Console.WriteLine(typeof(T).Name.Length + i.Length + typeof(U).Name.Length); } ##} """); [Fact] public Task TestInlineMethodWithGenericsArgumentsAcrossFile() => TestVerifier.TestBothKeepAndRemoveInlinedMethodInDifferentFileAsync( """ public partial class TestClass { private void Caller<U>() { Ca[||]llee<int, U>(1, 2, 3); } } """, """ public partial class TestClass { private void Callee<T, U>(params T[] i) { System.Console.WriteLine(typeof(T).Name.Length + i.Length + typeof(U).Name.Length); } } """, """ public partial class TestClass { private void Caller<U>() { System.Console.WriteLine(typeof(int).Name.Length + (new int[] { 1, 2, 3 }).Length + typeof(U).Name.Length); } } """, """ public partial class TestClass {## private void Callee<T, U>(params T[] i) { System.Console.WriteLine(typeof(T).Name.Length + i.Length + typeof(U).Name.Length); }## } """); [Fact] public Task TestAwaitExpressionInMethod1() => TestVerifier.TestBothKeepAndRemoveInlinedMethodInSameFileAsync( """ using System.Threading.Tasks; using System; public class TestClass { public Task<int> Caller(bool x) { System.Console.WriteLine(""); return Call[||]ee(10, x ? 1 : 2); } private async Task<int> Callee(int i, int j) { return await Task.FromResult(i + j); } } """, """ using System.Threading.Tasks; using System; public class TestClass { public Task<int> Caller(bool x) { System.Console.WriteLine(""); return Task.FromResult(10 + (x ? 1 : 2)); } ## private async Task<int> Callee(int i, int j) { return await Task.FromResult(i + j); } ##} """); [Fact] public Task TestAwaitExpressionInMethodAcrossFile() => TestVerifier.TestBothKeepAndRemoveInlinedMethodInDifferentFileAsync( """ using System.Threading.Tasks; public partial class TestClass { public Task<int> Caller(bool x) { System.Console.WriteLine(""); return Call[||]ee(10, x ? 1 : 2); } } """, """ using System.Threading.Tasks; public partial class TestClass { private async Task<int> Callee(int i, int j) { return await Task.FromResult(i + j); } } """, """ using System.Threading.Tasks; public partial class TestClass { public Task<int> Caller(bool x) { System.Console.WriteLine(""); return Task.FromResult(10 + (x ? 1 : 2)); } } """, """ using System.Threading.Tasks; public partial class TestClass {## private async Task<int> Callee(int i, int j) { return await Task.FromResult(i + j); }## } """); [Fact] public Task TestAwaitExpressionInMethod2() => TestVerifier.TestBothKeepAndRemoveInlinedMethodInSameFileAsync( """ using System.Threading.Tasks; using System; public class TestClass { public void Caller(bool x) { System.Console.WriteLine(""); var f = C[||]allee(); } private Func<Task> Callee() { return async () => await Task.Delay(100); } } """, """ using System.Threading.Tasks; using System; public class TestClass { public void Caller(bool x) { System.Console.WriteLine(""); var f = (Func<Task>)(async () => await Task.Delay(100)); } ## private Func<Task> Callee() { return async () => await Task.Delay(100); } ##} """); [Fact] public Task TestAwaitExpressionInMethod2AcrossFile() => TestVerifier.TestBothKeepAndRemoveInlinedMethodInDifferentFileAsync( """ using System.Threading.Tasks; using System; public partial class TestClass { public void Caller(bool x) { System.Console.WriteLine(""); var f = C[||]allee(); } } """, """ using System.Threading.Tasks; using System; public partial class TestClass { private Func<Task> Callee() { return async () => await Task.Delay(100); } } """, """ using System.Threading.Tasks; using System; public partial class TestClass { public void Caller(bool x) { System.Console.WriteLine(""); var f = (Func<Task>)(async () => await Task.Delay(100)); } } """, """ using System.Threading.Tasks; using System; public partial class TestClass {## private Func<Task> Callee() { return async () => await Task.Delay(100); }## } """); [Fact] public Task TestAwaitExpresssion1() => TestVerifier.TestBothKeepAndRemoveInlinedMethodInSameFileAsync( """ using System.Threading.Tasks; public class TestClass { public Task Caller() { return Cal[||]lee(); } private async Task Callee() { await Task.CompletedTask; } } """, """ using System.Threading.Tasks; public class TestClass { public Task Caller() { return Task.CompletedTask; } ## private async Task Callee() { await Task.CompletedTask; } ##} """); [Fact] public Task TestAwaitExpresssion2() => TestVerifier.TestBothKeepAndRemoveInlinedMethodInSameFileAsync( """ using System.Threading.Tasks; public class TestClass { public async Task Caller() { await Cal[||]lee().ConfigureAwait(false); } private async Task Callee() => await Task.CompletedTask; } """, """ using System.Threading.Tasks; public class TestClass { public async Task Caller() { await Task.CompletedTask.ConfigureAwait(false); } ## private async Task Callee() => await Task.CompletedTask; ##} """); [Fact] public Task TestAwaitExpresssion3() => TestVerifier.TestBothKeepAndRemoveInlinedMethodInSameFileAsync( """ using System.Threading.Tasks; public class TestClass { public Task<int> Caller() { return Cal[||]lee(); } private async Task<int> Callee() => await Task.FromResult(1); } """, """ using System.Threading.Tasks; public class TestClass { public Task<int> Caller() { return Task.FromResult(1); } ## private async Task<int> Callee() => await Task.FromResult(1); ##} """); [Fact] public Task TestAwaitExpresssion4() => TestVerifier.TestBothKeepAndRemoveInlinedMethodInSameFileAsync( """ using System.Threading.Tasks; public class TestClass { public void Caller() { var x = Cal[||]lee(); } private async Task<int> Callee() { return await Task.FromResult(await SomeCalculation()); } private async Task<int> SomeCalculation() => await Task.FromResult(10); } """, """ using System.Threading.Tasks; public class TestClass { public async void Caller() { var x = Task.FromResult(await SomeCalculation()); } ## private async Task<int> Callee() { return await Task.FromResult(await SomeCalculation()); } ## private async Task<int> SomeCalculation() => await Task.FromResult(10); } """); [Fact] public Task TestAwaitExpressionInMethod4AcrossFile() => TestVerifier.TestBothKeepAndRemoveInlinedMethodInDifferentFileAsync( """ using System.Threading.Tasks; public partial class TestClass { public void Caller() { var x = Cal[||]lee(); } private async Task<int> SomeCalculation() => await Task.FromResult(10); } """, """ using System.Threading.Tasks; public partial class TestClass { private async Task<int> Callee() { return await Task.FromResult(await SomeCalculation()); } } """, """ using System.Threading.Tasks; public partial class TestClass { public async void Caller() { var x = Task.FromResult(await SomeCalculation()); } private async Task<int> SomeCalculation() => await Task.FromResult(10); } """, """ using System.Threading.Tasks; public partial class TestClass {## private async Task<int> Callee() { return await Task.FromResult(await SomeCalculation()); }## } """); [Fact] public Task TestAwaitExpresssion5() { var diagnostic = new List<DiagnosticResult>() { // Await can't be used in non-async method. DiagnosticResult.CompilerError("CS4032").WithSpan(6, 33, 6, 56).WithArguments("int") }; return TestVerifier.TestBothKeepAndRemoveInlinedMethodInSameFileAsync( """ using System.Threading.Tasks; public class TestClass { public int Caller() { var x = Cal[||]lee(); return 1; } private async Task<int> Callee() { return await Task.FromResult(await SomeCalculation()); } private async Task<int> SomeCalculation() => await Task.FromResult(10); } """, """ using System.Threading.Tasks; public class TestClass { public int Caller() { var x = Task.FromResult(await SomeCalculation()); return 1; } ## private async Task<int> Callee() { return await Task.FromResult(await SomeCalculation()); } ## private async Task<int> SomeCalculation() => await Task.FromResult(10); } """, diagnosticResultsWhenKeepInlinedMethod: diagnostic, diagnosticResultsWhenRemoveInlinedMethod: diagnostic); } [Fact] public Task TestAwaitExpresssion6() => TestVerifier.TestBothKeepAndRemoveInlinedMethodInSameFileAsync( """ using System.Threading.Tasks; public class TestClass { public void Caller() { var x = Cal[||]lee().Result; } private async Task<int> Callee() { return await Task.FromResult(100); } } """, """ using System.Threading.Tasks; public class TestClass { public void Caller() { var x = Task.FromResult(100).Result; } ## private async Task<int> Callee() { return await Task.FromResult(100); } ##} """); [Fact] public Task TestAwaitExpressionInLambda() => TestVerifier.TestBothKeepAndRemoveInlinedMethodInSameFileAsync( """ using System; using System.Threading.Tasks; public class TestClass { private void Method() { Func<bool, Task<int>> x1 = (x) => { System.Console.WriteLine(""); return Call[||]ee(); }; } private async Task<int> Callee() { return await Task.FromResult(10); } } """, """ using System; using System.Threading.Tasks; public class TestClass { private void Method() { Func<bool, Task<int>> x1 = (x) => { System.Console.WriteLine(""); return Task.FromResult(10); }; } ## private async Task<int> Callee() { return await Task.FromResult(10); } ##} """); [Fact] public Task TestAwaitExpressionInLocalMethod() => TestVerifier.TestBothKeepAndRemoveInlinedMethodInSameFileAsync( """ using System.Threading.Tasks; public class TestClass { private void Method() { Task<int> Caller(bool x) { System.Console.WriteLine(""); return Call[||]ee(10, x ? 1 : 2); } } private async Task<int> Callee(int i, int j) { return await Task.FromResult(i + j); } } """, """ using System.Threading.Tasks; public class TestClass { private void Method() { Task<int> Caller(bool x) { System.Console.WriteLine(""); return Task.FromResult(10 + (x ? 1 : 2)); } } ## private async Task<int> Callee(int i, int j) { return await Task.FromResult(i + j); } ##} """); [Fact] public Task TestInlineMethodForLambda1() => TestVerifier.TestBothKeepAndRemoveInlinedMethodInSameFileAsync( """ using System; public class TestClass { public void Caller() { Call[||]ee()(10); } private Func<int, int> Callee() => i => 1; } """, """ using System; public class TestClass { public void Caller() { ((Func<int, int>)(i => 1))(10); } ## private Func<int, int> Callee() => i => 1; ##} """); [Fact] public Task TestInlineMethodForLambda2() => TestVerifier.TestBothKeepAndRemoveInlinedMethodInSameFileAsync( """ using System; using System.Threading.Tasks; public class TestClass { public void Caller() { var x = Call[||]ee(); } private Func<Task> Callee() => async () => await Task.CompletedTask; } """, """ using System; using System.Threading.Tasks; public class TestClass { public void Caller() { var x = (Func<Task>)(async () => await Task.CompletedTask); } ## private Func<Task> Callee() => async () => await Task.CompletedTask; ##} """); [Fact] public Task TestInlineWithinDoStatement() => TestVerifier.TestBothKeepAndRemoveInlinedMethodInSameFileAsync( """ public class TestClass { private void Caller() { do { } while(Cal[||]lee(SomeInt()) == 1); } private int Callee(int i) { return i + 1; } private int SomeInt() => 10; } """, """ public class TestClass { private void Caller() { do { } while(SomeInt() + 1 == 1); } ## private int Callee(int i) { return i + 1; } ## private int SomeInt() => 10; } """); [Fact] public Task TestInlineWithinForStatement() => TestVerifier.TestBothKeepAndRemoveInlinedMethodInSameFileAsync( """ public class TestClass { private void Caller() { for (int i = Ca[||]llee(SomeInt()); i < 10; i++) { } } private int Callee(int i) { return i + 1; } private int SomeInt() => 10; } """, """ public class TestClass { private void Caller() { for (int i = SomeInt() + 1; i < 10; i++) { } } ## private int Callee(int i) { return i + 1; } ## private int SomeInt() => 10; } """); [Fact] public Task TestInlineWithinIfStatement() => TestVerifier.TestBothKeepAndRemoveInlinedMethodInSameFileAsync( """ public class TestClass { private void Caller() { if (Ca[||]llee(SomeInt()) == 1) { } } private int Callee(int i) { return i + 1; } private int SomeInt() => 10; } """, """ public class TestClass { private void Caller() { if (SomeInt() + 1 == 1) { } } ## private int Callee(int i) { return i + 1; } ## private int SomeInt() => 10; } """); [Fact] public Task TestInlineWithinLockStatement() => TestVerifier.TestBothKeepAndRemoveInlinedMethodInSameFileAsync( """ public class TestClass { private void Caller() { lock (Ca[||]llee(SomeInt())) { } } private string Callee(int i) { return "Hello" + i; } private int SomeInt() => 10; } """, """ public class TestClass { private void Caller() { lock ("Hello" + SomeInt()) { } } ## private string Callee(int i) { return "Hello" + i; } ## private int SomeInt() => 10; } """); [Fact] public Task TestInlineWithinReturnStatement() => TestVerifier.TestBothKeepAndRemoveInlinedMethodInSameFileAsync( """ public class TestClass { private string Caller() { return Call[||]ee(SomeInt()); } private string Callee(int i) { return "Hello" + i; } private int SomeInt() => 10; } """, """ public class TestClass { private string Caller() { return "Hello" + SomeInt(); } ## private string Callee(int i) { return "Hello" + i; } ## private int SomeInt() => 10; } """); [Fact] public Task TestInlineMethodWithinThrowStatement() => TestVerifier.TestBothKeepAndRemoveInlinedMethodInSameFileAsync( """ public class TestClass { private void Caller() { throw new System.Exception(Call[||]ee(SomeInt()) + ""); } private int Callee(int i) { return i + 20; } private int SomeInt() => 10; } """, """ public class TestClass { private void Caller() { throw new System.Exception(SomeInt() + 20 + ""); } ## private int Callee(int i) { return i + 20; } ## private int SomeInt() => 10; } """); [Fact] public Task TestInlineWithinWhileStatement() => TestVerifier.TestBothKeepAndRemoveInlinedMethodInSameFileAsync( """ public class TestClass { private void Caller() { while (Cal[||]lee(SomeInt()) == 1) {} } private int Callee(int i) { return i + 1; } private int SomeInt() => 10; } """, """ public class TestClass { private void Caller() { while (SomeInt() + 1 == 1) {} } ## private int Callee(int i) { return i + 1; } ## private int SomeInt() => 10; } """); [Fact] public Task TestInlineMethodWithinTryStatement() => TestVerifier.TestBothKeepAndRemoveInlinedMethodInSameFileAsync( """ public class TestClass { private void Calller() { try { } catch (System.Exception e) when (Ca[||]llee(e, SomeInt())) { } } private bool Callee(System.Exception e, int i) => i == 1; private int SomeInt() => 10; } """, """ public class TestClass { private void Calller() { try { } catch (System.Exception e) when (SomeInt() == 1) { } } ## private bool Callee(System.Exception e, int i) => i == 1; ## private int SomeInt() => 10; } """); [Fact] public Task TestInlineMethodWithinYieldReturnStatement() => TestVerifier.TestBothKeepAndRemoveInlinedMethodInSameFileAsync( """ public class TestClass2 { private System.Collections.Generic.IEnumerable<int> Calller() { yield return 1; yield return Cal[||]lee(SomeInt()); yield return 3; } private int Callee(int i) => i + 10; private int SomeInt() => 10; } """, """ public class TestClass2 { private System.Collections.Generic.IEnumerable<int> Calller() { yield return 1; yield return SomeInt() + 10; yield return 3; } ## private int Callee(int i) => i + 10; ## private int SomeInt() => 10; } """); [Fact] public Task TestInlineExtensionMethod1() => TestVerifier.TestBothKeepAndRemoveInlinedMethodInSameFileAsync( """ static class Program { static void Main(string[] args) { var value = 0; value.Ge[||]tNext(); } private static int GetNext(this int i) { return i + 1; } } """, """ static class Program { static void Main(string[] args) { var value = 0; int temp = value + 1; } ## private static int GetNext(this int i) { return i + 1; } ##} """); [Fact] public Task TestInlineExtensionMethod2() => TestVerifier.TestBothKeepAndRemoveInlinedMethodInSameFileAsync( """ static class Program { static void Main(string[] args) { var x = 0.Ge[||]tNext(); } private static int GetNext(this int i) { return i + 1; } } """, """ static class Program { static void Main(string[] args) { var x = 0 + 1; } ## private static int GetNext(this int i) { return i + 1; } ##} """); [Fact] public Task TestInlineExtensionMethod3() => TestVerifier.TestBothKeepAndRemoveInlinedMethodInSameFileAsync( """ static class Program { static void Main(string[] args) { GetInt().Ge[||]tNext(); } private static int GetInt() => 10; private static int GetNext(this int i) { return i + 1; } } """, """ static class Program { static void Main(string[] args) { int temp = GetInt() + 1; } private static int GetInt() => 10; ## private static int GetNext(this int i) { return i + 1; } ##} """); [Fact] public Task TestIsExpression() => TestVerifier.TestBothKeepAndRemoveInlinedMethodInSameFileAsync( """ public class TestClass { public bool Caller(int i, int j) { return Ca[||]llee(i, j) is int; } private bool Callee(int i, int j) { return i == j; } } """, """ public class TestClass { public bool Caller(int i, int j) { return (i == j) is int; } ## private bool Callee(int i, int j) { return i == j; } ##} """); [Fact] public Task TestUnaryPlusOperator() => TestVerifier.TestBothKeepAndRemoveInlinedMethodInSameFileAsync( """ public class TestClass { public int Caller() { return +Call[||]ee(); } private int Callee() { return 1 + 2; } } """, """ public class TestClass { public int Caller() { return +(1 + 2); } ## private int Callee() { return 1 + 2; } ##} """); [Fact] public Task TestLogicalNotExpression() => TestVerifier.TestBothKeepAndRemoveInlinedMethodInSameFileAsync( """ public class TestClass { public bool Caller(int i, int j) { return !Ca[||]llee(i, j); } private bool Callee(int i, int j) { return i == j; } } """, """ public class TestClass { public bool Caller(int i, int j) { return !(i == j); } ## private bool Callee(int i, int j) { return i == j; } ##} """); [Fact] public Task TestCastExpression() => TestVerifier.TestBothKeepAndRemoveInlinedMethodInSameFileAsync( """ public class TestClass { public char Caller(int i, int j) { return (char)Call[||]ee(i, j); } private int Callee(int i, int j) { return i + j; } } """, """ public class TestClass { public char Caller(int i, int j) { return (char)(i + j); } ## private int Callee(int i, int j) { return i + j; } ##} """); [Fact] public Task TestIsPatternExpression() => TestVerifier.TestBothKeepAndRemoveInlinedMethodInSameFileAsync( """ public class TestClass { public void Calller() { if (Ca[||]llee() is int i) { } } private int Callee() { return 1 | 2; } } """, """ public class TestClass { public void Calller() { if ((1 | 2) is int i) { } } ## private int Callee() { return 1 | 2; } ##} """); [Fact] public Task TestCoalesceExpression() => TestVerifier.TestBothKeepAndRemoveInlinedMethodInSameFileAsync( """ public class TestClass { public int Caller(int? c) { return 1 + Cal[||]lee(c); } private int Callee(int? c) { return c ?? 1; } } """, """ public class TestClass { public int Caller(int? c) { return 1 + (c ?? 1); } ## private int Callee(int? c) { return c ?? 1; } ##} """); [Fact] public Task TestCoalesceExpressionAsRightValue() => TestVerifier.TestBothKeepAndRemoveInlinedMethodInSameFileAsync( """ public class TestClass { public string Caller(string c) { return c ?? Cal[||]lee(null); } private string Callee(string c2) { return c2 ?? "Hello"; } } """, """ public class TestClass { public string Caller(string c) { return c ?? null ?? "Hello"; } ## private string Callee(string c2) { return c2 ?? "Hello"; } ##} """); [Fact] public Task TestSimpleMemberAccessExpression() => TestVerifier.TestBothKeepAndRemoveInlinedMethodInSameFileAsync( """ public class TestClass { public void Caller() { var x = C[||]allee().Length; } private string Callee() => "H" + "L"; } """, """ public class TestClass { public void Caller() { var x = ("H" + "L").Length; } ## private string Callee() => "H" + "L"; ##} """); [Fact] public Task TestSwitchExpression() => TestVerifier.TestBothKeepAndRemoveInlinedMethodInSameFileAsync(""" public class TestClass { private void Calller() { var x = C[||]allee() switch { 1 => 1, 2 => 2, _ => 3 }; } private int Callee() => 1 + 2; } """, """ public class TestClass { private void Calller() { var x = (1 + 2) switch { 1 => 1, 2 => 2, _ => 3 }; } ## private int Callee() => 1 + 2; ##} """); [Fact] public Task TestSuppressNullableWarningExpression() => TestVerifier.TestBothKeepAndRemoveInlinedMethodInSameFileAsync(""" #nullable enable public class TestClass { private object Calller(int x) { return Ca[||]llee(x)!; } private object Callee(int x) => x = 1; } """, """ #nullable enable public class TestClass { private object Calller(int x) { return (x = 1)!; } ## private object Callee(int x) => x = 1; ##} """); [Fact] public Task TestSimpleAssignmentExpression() => TestVerifier.TestBothKeepAndRemoveInlinedMethodInSameFileAsync(""" public class TestClass { private int Calller(int x) { return Ca[||]llee(x) + 1; } private int Callee(int x) => x = 1; } """, """ public class TestClass { private int Calller(int x) { return (x = 1) + 1; } ## private int Callee(int x) => x = 1; ##} """); [Theory] [InlineData("++")] [InlineData("--")] public Task TestPreExpression(string op) => TestVerifier.TestBothKeepAndRemoveInlinedMethodInSameFileAsync( """ public class TestClass { public void Caller() { int i = 1; Cal[||]lee(i); } private int Callee(int i) { return (op)i; } } """.Replace("(op)", op), """ public class TestClass { public void Caller() { int i = 1; (op)i; } ## private int Callee(int i) { return (op)i; } ##} """.Replace("(op)", op)); [Fact] public Task TestAwaitExpressionWithFireAndForgot() => TestVerifier.TestBothKeepAndRemoveInlinedMethodInSameFileAsync(""" using System.Threading.Tasks; public class TestClass { public async void Caller() { Cal[||]lee(); } private async Task Callee() { await Task.Delay(100); } } """, """ using System.Threading.Tasks; public class TestClass { public async void Caller() { Task.Delay(100); } ## private async Task Callee() { await Task.Delay(100); } ##} """); [Theory] [InlineData("++")] [InlineData("--")] public Task TestPostExpression(string op) => TestVerifier.TestBothKeepAndRemoveInlinedMethodInSameFileAsync( """ public class TestClass { public void Caller() { int i = 1; Cal[||]lee(i); } private int Callee(int i) { return i(op); } } """.Replace("(op)", op), """ public class TestClass { public void Caller() { int i = 1; i(op); } ## private int Callee(int i) { return i(op); } ##} """.Replace("(op)", op)); [Fact] public Task TestConditionalInvocationExpression1() => TestVerifier.TestBothKeepAndRemoveInlinedMethodInSameFileAsync( """ public class TestClass { public void Caller() { Cal[||]lee(); } private char[] Callee() => ("Hello" + "World")?.ToCharArray(); } """, """ public class TestClass { public void Caller() { ("Hello" + "World")?.ToCharArray(); } ## private char[] Callee() => ("Hello" + "World")?.ToCharArray(); ##} """); [Fact] public Task TestInlineLambdaInsideInvocation() => TestVerifier.TestBothKeepAndRemoveInlinedMethodInSameFileAsync(""" using System; public class TestClass { public void Caller() { var x = Cal[||]lee()(); } private Func<int> Callee() { return () => 1; } } """, """ using System; public class TestClass { public void Caller() { var x = ((Func<int>)(() => 1))(); } ## private Func<int> Callee() { return () => 1; } ##} """); [Fact] public Task TestInlineLambda1() => TestVerifier.TestBothKeepAndRemoveInlinedMethodInSameFileAsync(""" using System; using System.Threading.Tasks; public class TestClass { public void Caller() { var x = Cal[||]lee(); } private Func<Task> Callee() { return async () => await Task.CompletedTask; } } """, """ using System; using System.Threading.Tasks; public class TestClass { public void Caller() { var x = (Func<Task>)(async () => await Task.CompletedTask); } ## private Func<Task> Callee() { return async () => await Task.CompletedTask; } ##} """); [Fact] public Task TestInlineLambda2() => TestVerifier.TestBothKeepAndRemoveInlinedMethodInSameFileAsync(""" using System; using System.Threading.Tasks; public class TestClass { public void Caller() { var x = Cal[||]lee(); } private Func<Task<int>> Callee() { return async () => { return await Task.FromResult(100); }; } } """, """ using System; using System.Threading.Tasks; public class TestClass { public void Caller() { var x = (Func<Task<int>>)(async () => { return await Task.FromResult(100); }); } ## private Func<Task<int>> Callee() { return async () => { return await Task.FromResult(100); }; } ##} """); [Fact] public Task TestInlineTypeCast() => TestVerifier.TestBothKeepAndRemoveInlinedMethodInSameFileAsync(""" public class TestClass { public void Caller() { var x = Cal[||]lee(); } private long Callee() { return 1; } } """, """ public class TestClass { public void Caller() { var x = (long)1; } ## private long Callee() { return 1; } ##} """); [Fact] public Task TestNestedConditionalInvocationExpression1() => TestVerifier.TestBothKeepAndRemoveInlinedMethodInSameFileAsync(""" public class LinkedList { public LinkedList Next { get; } } public class TestClass { public void Caller() { var l = new LinkedList(); Cal[||]lee(l); } private string Callee(LinkedList l) { return l?.Next?.Next?.Next?.Next?.ToString(); } } """, """ public class LinkedList { public LinkedList Next { get; } } public class TestClass { public void Caller() { var l = new LinkedList(); l?.Next?.Next?.Next?.Next?.ToString(); } ## private string Callee(LinkedList l) { return l?.Next?.Next?.Next?.Next?.ToString(); } ##} """); [Fact] public Task TestNestedConditionalInvocationExpression2() => TestVerifier.TestBothKeepAndRemoveInlinedMethodInSameFileAsync(""" public class LinkedList { public LinkedList Next { get; } } public class TestClass { public void Caller() { var l = new LinkedList(); Cal[||]lee(l); } private string Callee(LinkedList l) { return l?.ToString(); } } """, """ public class LinkedList { public LinkedList Next { get; } } public class TestClass { public void Caller() { var l = new LinkedList(); l?.ToString(); } ## private string Callee(LinkedList l) { return l?.ToString(); } ##} """); [Fact] public Task TestNestedConditionalInvocationExpression3() => TestVerifier.TestBothKeepAndRemoveInlinedMethodInSameFileAsync(""" public class LinkedList { public LinkedList Next { get; } } public class TestClass { public void Caller() { var l = new LinkedList(); Cal[||]lee(l); } private string Callee(LinkedList l) { return l?.Next.ToString(); } } """, """ public class LinkedList { public LinkedList Next { get; } } public class TestClass { public void Caller() { var l = new LinkedList(); l?.Next.ToString(); } ## private string Callee(LinkedList l) { return l?.Next.ToString(); } ##} """); [Fact] public Task TestThrowStatement() => TestVerifier.TestBothKeepAndRemoveInlinedMethodInSameFileAsync(""" using System; public class TestClass { public void Caller() { Call[||]ee(); } private string Callee() { throw new Exception(); } } """, """ using System; public class TestClass { public void Caller() { throw new Exception(); } ## private string Callee() { throw new Exception(); } ##} """); [Fact] public Task TestThrowExpressionToThrowStatement() => TestVerifier.TestBothKeepAndRemoveInlinedMethodInSameFileAsync(""" using System; public class TestClass { public void Caller() { Call[||]ee(); } private string Callee() => throw new Exception(); } """, """ using System; public class TestClass { public void Caller() { throw new Exception(); } ## private string Callee() => throw new Exception(); ##} """); [Fact] public Task TestThrowExpression1() => TestVerifier.TestBothKeepAndRemoveInlinedMethodInSameFileAsync(""" using System; public class TestClass { public void Caller(bool a) { var x = a ? Call[||]ee() : "Hello"; } private string Callee() => throw new Exception(); } """, """ using System; public class TestClass { public void Caller(bool a) { var x = a ? throw new Exception() : "Hello"; } ## private string Callee() => throw new Exception(); ##} """); [Fact] public Task TestThrowExpression2() => TestVerifier.TestBothKeepAndRemoveInlinedMethodInSameFileAsync(""" using System; public class TestClass { public void Caller(bool a) => Ca[||]llee(); private string Callee() => throw new Exception(); } """, """ using System; public class TestClass { public void Caller(bool a) => throw new Exception(); ## private string Callee() => throw new Exception(); ##} """); [Fact] public Task TestThrowStatementToThrowExpression() => TestVerifier.TestBothKeepAndRemoveInlinedMethodInSameFileAsync(""" using System; public class TestClass { public void Caller(bool a) { var x = a ? Call[||]ee() : "Hello"; } private string Callee() { throw new Exception(); } } """, """ using System; public class TestClass { public void Caller(bool a) { var x = a ? throw new Exception() : "Hello"; } ## private string Callee() { throw new Exception(); } ##} """); [Fact] public Task TestWriteSingleParameter() => TestVerifier.TestBothKeepAndRemoveInlinedMethodInSameFileAsync(""" public class TestClass { public void Caller(bool a) { var x = C[||]allee(a ? 10 : 100); } private int Callee(int c) { return c = 1000; } } """, """ public class TestClass { public void Caller(bool a) { int c = a ? 10 : 100; var x = c = 1000; } ## private int Callee(int c) { return c = 1000; } ##} """); [Fact] public Task TestReadMultipleTimesForParameter() => TestVerifier.TestBothKeepAndRemoveInlinedMethodInSameFileAsync(""" public class TestClass { public void Caller(bool a) { var x = C[||]allee(a ? 10 : 100, a); } private int Callee(int c, bool a) { return a ? c + 1000 : c + 10000; } } """, """ public class TestClass { public void Caller(bool a) { int c = a ? 10 : 100; var x = a ? c + 1000 : c + 10000; } ## private int Callee(int c, bool a) { return a ? c + 1000 : c + 10000; } ##} """); [Fact] public Task TestInlineInArrowFunction1() => TestVerifier.TestBothKeepAndRemoveInlinedMethodInSameFileAsync(""" public class TestClass { public int Caller(bool a) => Ca[||]llee(SomeInt(), a); private int SomeInt() => 1; private int Callee(int c, bool a) { return a ? c + 1000 : c + 10000; } } """, """ public class TestClass { public int Caller(bool a) => a ? SomeInt() + 1000 : SomeInt() + 10000; private int SomeInt() => 1; ## private int Callee(int c, bool a) { return a ? c + 1000 : c + 10000; } ##} """); [Fact] public Task TestInlineInArrowFunction2() { var diagnostic = new List<DiagnosticResult>() { // User is inlining method in arrow function, there is no place to put the declaration of 'i' DiagnosticResult.CompilerError("CS0103").WithSpan(3, 29, 3, 30).WithArguments("i") }; return TestVerifier.TestBothKeepAndRemoveInlinedMethodInSameFileAsync(""" public class TestClass { public void Caller() => Ca[||]llee(out var j); private void Callee(out int i) => i = 1; } """, """ public class TestClass { public void Caller() => i = 1; ## private void Callee(out int i) => i = 1; ##} """, diagnostic, diagnostic); } [Fact] public Task TestInlineInArrowProperty1() => TestVerifier.TestBothKeepAndRemoveInlinedMethodInSameFileAsync(""" public class TestClass { private const int i = 10; public int Caller => Ca[||]llee(); private int Callee() => i + 1; } """, """ public class TestClass { private const int i = 10; public int Caller => i + 1; ## private int Callee() => i + 1; ##} """); [Fact] public Task TestInlineInArrowProperty2() => TestVerifier.TestBothKeepAndRemoveInlinedMethodInSameFileAsync(""" public class TestClass { private const int i = 10; public int Caller { get => Cal[||]lee(); } private int Callee() => i + 1; } """, """ public class TestClass { private const int i = 10; public int Caller { get => i + 1; } ## private int Callee() => i + 1; ##} """); [Fact] public Task TestInlineInArrowLambda1() { var diagnostic = new List<DiagnosticResult>() { // User is inlining method in arrow function, there is no place to put the declaration of 'i' DiagnosticResult.CompilerError("CS0103").WithSpan(6, 26, 6, 27).WithArguments("i") }; return TestVerifier.TestBothKeepAndRemoveInlinedMethodInSameFileAsync(""" using System; public class TestClass { public void Caller() { Action f = () => Cal[||]lee(out var j); } private void Callee(out int i) => i = 1; } """, """ using System; public class TestClass { public void Caller() { Action f = () => i = 1; } ## private void Callee(out int i) => i = 1; ##} """, diagnostic, diagnostic); } [Fact] public Task TestInlineInArrowLambda2() => TestVerifier.TestBothKeepAndRemoveInlinedMethodInSameFileAsync(""" using System; public class TestClass { public void Caller() { Action f = () => { Cal[||]lee(out var j); }; } private void Callee(out int i) => i = 1; } """, """ using System; public class TestClass { public void Caller() { Action f = () => { int j = 1; }; } ## private void Callee(out int i) => i = 1; ##} """); [Fact] public Task TestInlineInLocalFunction() => TestVerifier.TestBothKeepAndRemoveInlinedMethodInSameFileAsync(""" using System; public class TestClass { public void Caller() { void Helper() { Cal[||]lee(out var j); } } private void Callee(out int i) => i = 1; } """, """ using System; public class TestClass { public void Caller() { void Helper() { int j = 1; } } ## private void Callee(out int i) => i = 1; ##} """); [Fact] public Task TestForPartialMethod1() => TestVerifier.TestBothKeepAndRemoveInlinedMethodInDifferentFileAsync( """ public partial class TestClass { void Caller() { Call[||]ee(); } } """, """ public partial class TestClass { partial void Callee(); partial void Callee() { System.Console.WriteLine("10"); } } """, """ public partial class TestClass { void Caller() { System.Console.WriteLine("10"); } } """, """ public partial class TestClass { partial void Callee(); ## partial void Callee() { System.Console.WriteLine("10"); } ##} """); [Fact] public Task TestForExtendedPartialMethod1() => TestVerifier.TestInRegularScriptsInDifferentFilesAsync( """ public partial class TestClass { void Caller() { Call[||]ee(); } } """, """ public partial class TestClass { private partial void Callee(); private partial void Callee() { System.Console.WriteLine("10"); } } """, """ public partial class TestClass { void Caller() { System.Console.WriteLine("10"); } } """, """ public partial class TestClass { private partial void Callee(); private partial void Callee() { System.Console.WriteLine("10"); } } """, keepInlinedMethod: true); [Fact] public Task TestForPartialMethod2() => TestVerifier.TestInRegularAndScriptInTheSameFileAsync( """ public partial class TestClass { partial void Caller() { Call[||]ee(); } } public partial class TestClass { partial void Caller(); partial void Callee(); partial void Callee() { System.Console.WriteLine("10"); } } """, """ public partial class TestClass { partial void Caller() { System.Console.WriteLine("10"); } } public partial class TestClass { partial void Caller(); partial void Callee(); partial void Callee() { System.Console.WriteLine("10"); } } """, keepInlinedMethod: true); [Fact] public Task TestForExtendedPartialMethod2() => TestVerifier.TestInRegularAndScriptInTheSameFileAsync( """ public partial class TestClass { private partial void Caller() { Call[||]ee(); } } public partial class TestClass { private partial void Caller(); private partial void Callee(); private partial void Callee() { System.Console.WriteLine("10"); } } """, """ public partial class TestClass { private partial void Caller() { System.Console.WriteLine("10"); } } public partial class TestClass { private partial void Caller(); private partial void Callee(); private partial void Callee() { System.Console.WriteLine("10"); } } """, keepInlinedMethod: true); [Fact] public Task TestForMultipleFieldsInFieldDeclaration() => TestVerifier.TestInRegularAndScriptInTheSameFileAsync( """ static class C { static readonly object A = [||]M(), B = M(); private static object M() => null!; } """, """ static class C { static readonly object A = null!, B = M(); private static object M() => null!; } """, keepInlinedMethod: true); [Fact] public Task TestForMultipleFieldsInFieldDeclaration2() => TestVerifier.TestInRegularAndScriptInTheSameFileAsync( """ static class C { static readonly object A = M(), B = [||]M(); private static object M() => null!; } """, """ static class C { static readonly object A = M(), B = null!; private static object M() => null!; } """, keepInlinedMethod: true); [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/81406")] public Task TestInlineRecursiveCall() => new TestVerifier { TestCode = """ class C { private void M() { System.Console.WriteLine(); [||]M(); } private void N() { M(); } } """, FixedCode = """ class C { private void M() { System.Console.WriteLine(); M(); } private void N() { M(); } } """, }.RunAsync(); }