Exemplo n.º 1
0
        public void Lambda(string code, Search search, string expected)
        {
            var testCode = @"
namespace RoslynSandbox
{
    using System;

    internal class Foo
    {
        internal Foo()
        {
            Func<int> temp = () => 1;
        }

        internal static int StaticCreateIntStatementBody()
        {
            return 1;
        }
    }
}";

            testCode = testCode.AssertReplace("Func<int> temp = () => 1", code);
            var syntaxTree    = CSharpSyntaxTree.ParseText(testCode);
            var compilation   = CSharpCompilation.Create("test", new[] { syntaxTree }, MetadataReferences.FromAttributes());
            var semanticModel = compilation.GetSemanticModel(syntaxTree);
            var value         = syntaxTree.FindEqualsValueClause(code).Value;

            using (var pooled = ReturnValueWalker.Borrow(value, search, semanticModel, CancellationToken.None))
            {
                var actual = string.Join(", ", pooled);
                Assert.AreEqual(expected, actual);
            }
        }
        public static void ReturnNullCoalesce()
        {
            var code              = @"
namespace N
{
    public class C
    {
        public C()
        {
            var temp = ReturnNullCoalesce(null);
        }

        private static string ReturnNullCoalesce(string text)
        {
            return text ?? string.Empty;
        }
    }
}";
            var syntaxTree        = CSharpSyntaxTree.ParseText(code);
            var compilation       = CSharpCompilation.Create("test", new[] { syntaxTree }, MetadataReferences.FromAttributes());
            var semanticModel     = compilation.GetSemanticModel(syntaxTree);
            var methodDeclaration = syntaxTree.FindEqualsValueClause("var temp = ReturnNullCoalesce(null)").Value;

            using var returnValues = ReturnValueWalker.Borrow(methodDeclaration, ReturnValueSearch.Recursive, semanticModel, CancellationToken.None);
            Assert.AreEqual("null, string.Empty", string.Join(", ", returnValues));
        }
        public static void AwaitSyntaxError(ReturnValueSearch search, string expected)
        {
            var code          = @"
using System.Threading.Tasks;

internal class C
{
    internal static async Task M()
    {
        var text = await CreateAsync().ConfigureAwait(false);
    }

    internal static async Task<string> CreateAsync()
    {
        await Task.Delay(0);
        return await Task.SyntaxError(() => new string(' ', 1)).ConfigureAwait(false);
    }
}";
            var syntaxTree    = CSharpSyntaxTree.ParseText(code);
            var compilation   = CSharpCompilation.Create("test", new[] { syntaxTree }, MetadataReferences.FromAttributes());
            var semanticModel = compilation.GetSemanticModel(syntaxTree);
            var value         = syntaxTree.FindExpression("await CreateAsync().ConfigureAwait(false)");

            using var pooled = ReturnValueWalker.Borrow(value, search, semanticModel, CancellationToken.None);
            var actual = string.Join(", ", pooled);

            Assert.AreEqual(expected, actual);
        }
        public static void Lambda(string expression, ReturnValueSearch search, string expected)
        {
            var code          = @"
namespace N
{
    using System;

    internal class C
    {
        internal C()
        {
            Func<int> temp = () => 1;
        }

        internal static int StaticCreateIntStatementBody()
        {
            return 1;
        }
    }
}".AssertReplace("Func<int> temp = () => 1", expression);
            var syntaxTree    = CSharpSyntaxTree.ParseText(code);
            var compilation   = CSharpCompilation.Create("test", new[] { syntaxTree }, MetadataReferences.FromAttributes());
            var semanticModel = compilation.GetSemanticModel(syntaxTree);
            var value         = syntaxTree.FindEqualsValueClause(expression).Value;

            using var returnValues = ReturnValueWalker.Borrow(value, search, semanticModel, CancellationToken.None);
            var actual = string.Join(", ", returnValues);

            Assert.AreEqual(expected, actual);
        }
Exemplo n.º 5
0
        public static void ReturnTernary()
        {
            var code              = @"
namespace N
{
    public class C
    {
        public C()
        {
            var temp = ReturnTernary(true);
        }

        private static int ReturnTernary(bool b)
        {
            return b ? 1 : 2;
        }
    }
}";
            var syntaxTree        = CSharpSyntaxTree.ParseText(code);
            var compilation       = CSharpCompilation.Create("test", new[] { syntaxTree }, MetadataReferences.FromAttributes());
            var semanticModel     = compilation.GetSemanticModel(syntaxTree);
            var methodDeclaration = syntaxTree.FindEqualsValueClause("var temp = ReturnTernary(true)").Value;

            using var walker = ReturnValueWalker.Borrow(methodDeclaration, ReturnValueSearch.Recursive, semanticModel, CancellationToken.None);
            Assert.AreEqual("1, 2", string.Join(", ", walker.ReturnValues));
        }
Exemplo n.º 6
0
        public static void RecursiveWithOptionalParameter()
        {
            var code          = @"
namespace N
{
    using System;
    using System.Collections.Generic;

    public abstract class C
    {
        public C(IDisposable disposable)
        {
            var local = disposable;
            local = WithOptionalParameter(local);
        }

        private static IDisposable WithOptionalParameter(IDisposable parameter, IEnumerable<IDisposable> values = null)
        {
            if (values == null)
            {
                return WithOptionalParameter(parameter, new[] { parameter });
            }

            return parameter;
        }
    }
}";
            var syntaxTree    = CSharpSyntaxTree.ParseText(code);
            var compilation   = CSharpCompilation.Create("test", new[] { syntaxTree }, MetadataReferences.FromAttributes());
            var semanticModel = compilation.GetSemanticModel(syntaxTree);
            var value         = syntaxTree.FindInvocation("WithOptionalParameter(local)");

            using var walker = ReturnValueWalker.Borrow(value, ReturnValueSearch.Recursive, semanticModel, CancellationToken.None);
            Assert.AreEqual("disposable", string.Join(", ", walker.ReturnValues));
        }
Exemplo n.º 7
0
 public static void ProcessReturnStatement(ISymbol local, BlockSyntax block, SemanticModel semanticModel, CancellationToken cancellationToken,
                                           RefCounterStatus status)
 {
     using (var walker = ReturnValueWalker.Borrow(block, Search.TopLevel, semanticModel, cancellationToken))
     {
         foreach (var value in walker)
         {
             var returnedSymbol = semanticModel.GetSymbolSafe(value, cancellationToken);
             if (SymbolComparer.Equals(local, returnedSymbol))
             {
                 var  method = block.FirstAncestor <MethodDeclarationSyntax>();
                 var  access = block.FirstAncestor <AccessorDeclarationSyntax>();
                 bool isGet  = false;
                 if (method != null)
                 {
                     isGet = KnownSymbol.IsGetMethodName(method.Identifier.ToString());
                 }
                 else if (access != null)
                 {
                     isGet = true;
                 }
                 if (isGet)
                 {
                     status.RemainRef("return value from get method", value.GetLocation());
                 }
                 else
                 {
                     status.ReleaseReference("return value from non get", value.GetLocation());
                 }
             }
         }
     }
 }
Exemplo n.º 8
0
        public void AsyncAwaitRecursive(string code, ReturnValueSearch search, string expected)
        {
            var testCode = @"
namespace RoslynSandbox
{
    using System;
    using System.Threading.Tasks;

    public class Disposable : IDisposable
    {
        public void Dispose()
        {
        }
    }

    internal class Foo
    {
        internal async Task Bar()
        {
            var value = await RecursiveAsync();
        }

        internal static Task<int> RecursiveAsync() => RecursiveAsync();

        internal static Task<int> RecursiveAsync(int arg) => RecursiveAsync(arg);

        private static async Task<int> RecursiveAsync1(int value)
        {
            return await RecursiveAsync2(value);
        }

        private static async Task<int> RecursiveAsync2(int value)
        {
            return await RecursiveAsync1(value);
        }

        private static Task<int> RecursiveAsync3(int value)
        {
            return RecursiveAsync4(value);
        }

        private static async Task<int> RecursiveAsync4(int value)
        {
            return await RecursiveAsync3(value);
        }
    }
}".AssertReplace("var value = await RecursiveAsync()", $"var value = {code}");

            var syntaxTree    = CSharpSyntaxTree.ParseText(testCode);
            var compilation   = CSharpCompilation.Create("test", new[] { syntaxTree }, MetadataReferences.FromAttributes());
            var semanticModel = compilation.GetSemanticModel(syntaxTree);
            var value         = syntaxTree.FindEqualsValueClause(code).Value;

            using (var returnValues = ReturnValueWalker.Borrow(value, search, semanticModel, CancellationToken.None))
            {
                Assert.AreEqual(expected, string.Join(", ", returnValues));
            }
        }
Exemplo n.º 9
0
        public void ValidationErrorToStringConverter()
        {
            var testCode          = @"
namespace RoslynSandbox
{
     using System;
    using System.Globalization;
    using System.Windows.Controls;
    using System.Windows.Data;

    public class ValidationErrorToStringConverter : IValueConverter
    {
        /// <summary> Gets the default instance </summary>
        public static readonly ValidationErrorToStringConverter Default = new ValidationErrorToStringConverter();

        /// <inheritdoc />
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            if (value is string text)
            {
                return text;
            }

            if (value is ValidationResult result)
            {
                return this.Convert(result.ErrorContent, targetType, parameter, culture);
            }

            if (value is ValidationError error)
            {
                return this.Convert(error.ErrorContent, targetType, parameter, culture);
            }

            return value;
        }

        /// <inheritdoc />
        object IValueConverter.ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotSupportedException($""{this.GetType().Name} only supports one-way conversion."");
        }
    }
}";
            var syntaxTree        = CSharpSyntaxTree.ParseText(testCode);
            var compilation       = CSharpCompilation.Create("test", new[] { syntaxTree }, MetadataReferences.FromAttributes());
            var semanticModel     = compilation.GetSemanticModel(syntaxTree);
            var methodDeclaration = syntaxTree.FindMethodDeclaration("Convert");

            using (var returnValues = ReturnValueWalker.Borrow(methodDeclaration, ReturnValueSearch.Recursive, semanticModel, CancellationToken.None))
            {
                Assert.AreEqual("error.ErrorContent, result.ErrorContent, value", string.Join(", ", returnValues));
            }
        }
Exemplo n.º 10
0
        public void Property(string code, ReturnValueSearch search, string expected)
        {
            var testCode      = @"
namespace RoslynSandbox
{
    internal class Foo
    {
        private readonly int value = 1;

        internal Foo()
        {
            var temp = CalculatedExpressionBody;
        }

        public int CalculatedExpressionBody => 1;

        public int CalculatedStatementBody
        {
            get
            {
                return 1;
            }
        }

        public Foo ThisExpressionBody => this;

        public int CalculatedReturningFieldExpressionBody => this.value;

        public int CalculatedReturningFieldStatementBody
        {
            get
            {
                return this.value;
            }
        }
    }
}".AssertReplace("var temp = CalculatedExpressionBody", $"var temp = {code}");
            var syntaxTree    = CSharpSyntaxTree.ParseText(testCode);
            var compilation   = CSharpCompilation.Create("test", new[] { syntaxTree }, MetadataReferences.FromAttributes());
            var semanticModel = compilation.GetSemanticModel(syntaxTree);
            var value         = syntaxTree.FindEqualsValueClause(code).Value;

            using (var returnValues = ReturnValueWalker.Borrow(value, search, semanticModel, CancellationToken.None))
            {
                var actual = string.Join(", ", returnValues);
                Assert.AreEqual(expected, actual);
            }
        }
Exemplo n.º 11
0
        public void ChainedExtensionMethod()
        {
            var testCode          = @"
namespace RoslynSandbox
{
    using System;

    public class Foo
    {
        public void Bar(int i)
        {
            var value = i.AsDisposable().AsDisposable();
        }
    }

    public static class Ext
    {
        public static IDisposable AsDisposable(this int i) => new Disposable();

        public static IDisposable AsDisposable(this IDisposable d) => new WrappingDisposable(d);
    }

    public sealed class WrappingDisposable : IDisposable
    {
        private readonly IDisposable inner;

        public WrappingDisposable(IDisposable inner)
        {
            this.inner = inner;
        }

        public void Dispose()
        {
            this.inner.Dispose();
        }
    }
}";
            var syntaxTree        = CSharpSyntaxTree.ParseText(testCode);
            var compilation       = CSharpCompilation.Create("test", new[] { syntaxTree }, MetadataReferences.FromAttributes());
            var semanticModel     = compilation.GetSemanticModel(syntaxTree);
            var methodDeclaration = syntaxTree.FindEqualsValueClause("var value = i.AsDisposable().AsDisposable()").Value;

            using (var returnValues = ReturnValueWalker.Borrow(methodDeclaration, ReturnValueSearch.Recursive, semanticModel, CancellationToken.None))
            {
                Assert.AreEqual("new WrappingDisposable(d)", returnValues.Single().ToString());
            }
        }
        public static void PropertyRecursive(string expression, ReturnValueSearch search, string expected)
        {
            var code          = @"
namespace N
{
    internal class C
    {
        internal C()
        {
            var temp = StaticRecursiveExpressionBody;
        }

        public static int StaticRecursiveExpressionBody => StaticRecursiveExpressionBody;

        public static int StaticRecursiveStatementBody
        {
            get
            {
                return StaticRecursiveStatementBody;
            }
        }

        public int RecursiveExpressionBody => this.RecursiveExpressionBody;

        public int RecursiveStatementBody
        {
            get
            {
                return this.RecursiveStatementBody;
            }
        }
    }
}".AssertReplace("var temp = StaticRecursiveExpressionBody", $"var temp = {expression}");
            var syntaxTree    = CSharpSyntaxTree.ParseText(code);
            var compilation   = CSharpCompilation.Create("test", new[] { syntaxTree }, MetadataReferences.FromAttributes());
            var semanticModel = compilation.GetSemanticModel(syntaxTree);
            var value         = syntaxTree.FindEqualsValueClause(expression).Value;

            using var returnValues = ReturnValueWalker.Borrow(value, search, semanticModel, CancellationToken.None);
            var actual = string.Join(", ", returnValues);

            Assert.AreEqual(expected, actual);
        }
        public static void AsyncAwait(string expression, ReturnValueSearch search, string expected)
        {
            var code = @"
namespace N
{
    using System;
    using System.Threading.Tasks;

    public class Disposable : IDisposable
    {
        public void Dispose()
        {
        }
    }

    internal class C
    {
        internal async Task M()
        {
            var value = await CreateStringAsync();
        }

        internal static int CreateInt() => 1;

        internal static async Task<string> CreateStringAsync()
        {
            await Task.Delay(0);
            return new string(' ', 1);
        }

        internal static async Task<int> CreateIntAsync()
        {
            await Task.Delay(0);
            return 1;
        }

        internal static Task<int> ReturnTaskFromResultAsync() => Task.FromResult(1);

        internal static Task<int> ReturnTaskFromResultAsync(int arg) => Task.FromResult(arg);

        internal static async Task<string> ReturnAwaitTaskRunAsync() => await Task.Run(() => new string(' ', 1));

        internal static async Task<string> ReturnAwaitTaskRunConfigureAwaitAsync() => await Task.Run(() => new string(' ', 1)).ConfigureAwait(false);

        internal static Task<int> CreateAsync(int arg)
        {
            switch (arg)
            {
                case 0:
                    return Task.FromResult(1);
                case 1:
                    return Task.FromResult(arg);
                case 2:
                    return Task.Run(() => 2);
                case 3:
                    return Task.Run(() => arg);
                case 4:
                    return Task.Run(() => { return 3; });
                default:
                    return Task.Run(() => { return arg; });
            }
        }
    }
}".AssertReplace("var value = await CreateStringAsync()", $"var value = {expression}");

            var syntaxTree    = CSharpSyntaxTree.ParseText(code);
            var compilation   = CSharpCompilation.Create("test", new[] { syntaxTree }, MetadataReferences.FromAttributes());
            var semanticModel = compilation.GetSemanticModel(syntaxTree);
            var value         = syntaxTree.FindEqualsValueClause(expression).Value;

            using var returnValues = ReturnValueWalker.Borrow(value, search, semanticModel, CancellationToken.None);
            Assert.AreEqual(expected, string.Join(", ", returnValues));
        }
        public static void CallRecursive(string expression, ReturnValueSearch search, string expected)
        {
            var code          = @"
namespace N
{
    using System;
    using System.Collections.Generic;
    using System.IO;

    internal class C
    {
        internal C()
        {
            var temp = Recursive();
        }

        public static int Recursive() => Recursive();

        public static int Recursive(int arg) => Recursive(arg);

        public static bool Recursive(bool flag)
        {
            if (flag)
            {
                return Recursive(!flag);
            }

            return flag;
        }

        private static int RecursiveWithOptional(int arg, IEnumerable<int> args = null)
        {
            if (arg == null)
            {
                return RecursiveWithOptional(arg, new[] { arg });
            }

            return arg;
        }

        private static int Recursive1(int value)
        {
            return Recursive2(value);
        }

        private static int Recursive2(int value)
        {
            return Recursive1(value);
        }

        private static IReadOnlyList<IDisposable> Flatten(IReadOnlyList<IDisposable> source, List<IDisposable> result = null)
        {
            result = result ?? new List<IDisposable>();
            result.AddRange(source);
            foreach (var condition in source)
            {
                Flatten(new[] { condition }, result);
            }

            return result;
        }
    }
}".AssertReplace("var temp = Recursive()", $"var temp = {expression}");
            var syntaxTree    = CSharpSyntaxTree.ParseText(code);
            var compilation   = CSharpCompilation.Create("test", new[] { syntaxTree }, MetadataReferences.FromAttributes());
            var semanticModel = compilation.GetSemanticModel(syntaxTree);
            var value         = syntaxTree.FindEqualsValueClause(expression).Value;

            using var returnValues = ReturnValueWalker.Borrow(value, search, semanticModel, CancellationToken.None);
            var actual = string.Join(", ", returnValues);

            Assert.AreEqual(expected, actual);
        }
        public static void Call(string expression, ReturnValueSearch search, string expected)
        {
            var code          = @"
namespace N
{
    using System;
    using System.Collections.Generic;
    using System.IO;

    internal class C
    {
        internal C()
        {
            var temp = StaticCreateIntStatementBody();
        }

        internal static int StaticCreateIntStatementBody()
        {
            return 1;
        }

        internal static int StaticCreateIntExpressionBody() => 2;

        internal static int IdStatementBody(int arg)
        {
            return arg;
        }

        internal static int IdExpressionBody(int arg) => arg;

        internal static int OptionalIdExpressionBody(int arg = 1) => arg;

        internal static int CallingIdExpressionBody(int arg1) => IdExpressionBody(arg1);

        public static int AssigningToParameter(int arg)
        {
            if (true)
            {
                return arg;
            }
            else
            {
                if (true)
                {
                    arg = 2;
                }
                else
                {
                    arg = 3;
                }

                return arg;
            }

            return 4;
        }

        public static int ConditionalId(int arg)
        {
            if (true)
            {
                return arg;
            }

            return arg;
        }

        public static int ReturnLocal()
        {
            var local = 1;
            return local;
        }

        public static int ReturnLocalAssignedTwice(bool flag)
        {
            var local = 1;
            local = 2;
            if (flag)
            {
                return local;
            }

            local = 5;
            return 3;
        }

        public C ThisExpressionBody() => this;

        public static Stream ReturningFileOpenRead()
        {
            return System.IO.File.OpenRead(string.Empty);
        }

        public static Stream ReturningLocalFileOpenRead()
        {
            var stream = System.IO.File.OpenRead(string.Empty);
            return stream;
        }
    }
}".AssertReplace("var temp = StaticCreateIntStatementBody()", $"var temp = {expression}");
            var syntaxTree    = CSharpSyntaxTree.ParseText(code);
            var compilation   = CSharpCompilation.Create("test", new[] { syntaxTree }, MetadataReferences.FromAttributes());
            var semanticModel = compilation.GetSemanticModel(syntaxTree);
            var value         = syntaxTree.FindEqualsValueClause(expression).Value;

            using var returnValues = ReturnValueWalker.Borrow(value, search, semanticModel, CancellationToken.None);
            var actual = string.Join(", ", returnValues);

            Assert.AreEqual(expected, actual);
        }
Exemplo n.º 16
0
        public void AsyncAwait(string code, Search search, string expected)
        {
            var testCode = @"
namespace RoslynSandbox
{
    using System;
    using System.Threading.Tasks;

    public class Disposable : IDisposable
    {
        public void Dispose()
        {
        }
    }

    internal class Foo
    {
        internal async Task Bar()
        {
            var value = // Meh();
        }

        internal static async Task<int> RecursiveAsync() => RecursiveAsync();

        internal static async Task<int> RecursiveAsync(int arg) => RecursiveAsync(arg);

        internal static async Task<string> CreateStringAsync()
        {
            await Task.Delay(0);
            return new string(' ', 1);
        }

        internal static async Task<string> ReturnAwaitTaskRunAsync()
        {
            await Task.Delay(0);
            return await Task.Run(() => new string(' ', 1)).ConfigureAwait(false);
        }

        internal static Task<int> CreateAsync(int arg)
        {
            switch (arg)
            {
                case 0:
                    return Task.FromResult(1);
                case 1:
                    return Task.FromResult(arg);
                case 2:
                    return Task.Run(() => 2);
                case 3:
                    return Task.Run(() => arg);
                case 4:
                    return Task.Run(() => { return 3; });
                default:
                    return Task.Run(() => { return arg; });
            }
        }

        internal static async int CreateInt() => 1;

        private static async Task<int> RecursiveAsync1(int value)
        {
            return await RecursiveAsync2(value);
        }
        
        private static async Task<int> RecursiveAsync2(int value)
        {
            return await RecursiveAsync1(value);
        }

        private static async Task<int> RecursiveAsync3(int value)
        {
            return RecursiveAsync4(value);
        }
        
        private static async Task<int> RecursiveAsync4(int value)
        {
            return await RecursiveAsync3(value);
        }
    }
}";

            testCode = testCode.AssertReplace("// Meh()", code);
            var syntaxTree    = CSharpSyntaxTree.ParseText(testCode);
            var compilation   = CSharpCompilation.Create("test", new[] { syntaxTree }, MetadataReferences.FromAttributes());
            var semanticModel = compilation.GetSemanticModel(syntaxTree);
            var value         = syntaxTree.FindEqualsValueClause(code).Value;

            using (var pooled = ReturnValueWalker.Borrow(value, search, semanticModel, CancellationToken.None))
            {
                Assert.AreEqual(expected, string.Join(", ", pooled));
            }
        }
Exemplo n.º 17
0
        public void Call(string code, Search search, string expected)
        {
            var testCode = @"
namespace RoslynSandbox
{
    using System;
    using System.Collections.Generic;

    internal class Foo
    {
        internal Foo()
        {
            var temp = // Meh();
        }

        internal static int StaticCreateIntStatementBody()
        {
            return 1;
        }

        internal static int StaticCreateIntExpressionBody() => 2;

        internal static int IdStatementBody(int arg)
        {
            return arg;
        }

        internal static int IdExpressionBody(int arg) => arg;

        internal static int OptionalIdExpressionBody(int arg = 1) => arg;

        internal static int CallingIdExpressionBody(int arg1) => IdExpressionBody(arg1);

        public static int AssigningToParameter(int arg)
        {
            if (true)
            {
                return arg;
            }
            else
            {
                if (true)
                {
                    arg = 2;
                }
                else
                {
                    arg = 3;
                }

                return arg;
            }

            return 4;
        }

        public static int ConditionalId(int arg)
        {
            if (true)
            {
                return arg;
            }

            return arg;
        }

        public static int ReturnLocal()
        {
            var local = 1;
            return local;
        }

        public static int ReturnLocalAssignedTwice(bool flag)
        {
            var local = 1;
            local = 2;
            if (flag)
            {
                return local;
            }

            local = 5;
            return 3;
        }

        public static int Recursive() => Recursive();

        public static int Recursive(int arg) => Recursive(arg);

        public static bool Recursive(bool flag)
        {
            if (flag)
            {
                return Recursive(!flag);
            }

            return flag;
        }

        public Foo ThisExpressionBody() => this;

        private static int RecursiveWithOptional(int arg, IEnumerable<int> args = null)
        {
            if (arg == null)
            {
                return RecursiveWithOptional(arg, new[] { arg });
            }

            return arg;
        }

        private static int Recursive1(int value)
        {
            return Recursive2(value);
        }

        private static int Recursive2(int value)
        {
            return Recursive1(value);
        }
    }
}";

            testCode = testCode.AssertReplace("// Meh()", code);
            var syntaxTree    = CSharpSyntaxTree.ParseText(testCode);
            var compilation   = CSharpCompilation.Create("test", new[] { syntaxTree }, MetadataReferences.FromAttributes());
            var semanticModel = compilation.GetSemanticModel(syntaxTree);
            var value         = syntaxTree.FindEqualsValueClause(code).Value;

            using (var pooled = ReturnValueWalker.Borrow(value, search, semanticModel, CancellationToken.None))
            {
                var actual = string.Join(", ", pooled);
                Assert.AreEqual(expected, actual);
            }
        }