File: TestSources.cs
Web Access
Project: src\src\Compilers\Test\Utilities\CSharp\Microsoft.CodeAnalysis.CSharp.Test.Utilities.csproj (Microsoft.CodeAnalysis.CSharp.Test.Utilities)
// 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
 
namespace Microsoft.CodeAnalysis.CSharp.Test.Utilities
{
    internal static class TestSources
    {
        internal static readonly string Span = @"
namespace System
{
    public readonly ref struct Span<T>
    {
        internal readonly T[] arr;
        internal readonly int start;
 
        public ref T this[int i] => ref arr[start + i];
        public override int GetHashCode() => 1;
        public int Length { get; }
        public bool IsEmpty => Length == 0;
 
        unsafe public Span(void* pointer, int length)
        {
            this.arr = Helpers.ToArray<T>(pointer, length);
            this.Length = length;
        }
 
        public Span(T[] arr)
        {
            this.arr = arr;
            this.Length = arr is null ? 0 : arr.Length;
        }
 
        public Span(T[] arr, int start, int length)
        {
            if (start + length > arr?.Length)
            {
                throw new ArgumentOutOfRangeException();
            }
 
            this.arr = arr;
            this.start = start;
            this.Length = length;
        }
 
        public static Span<T> Empty => default;
 
        public void CopyTo(Span<T> other)
        {
            Array.Copy(arr, start, other.arr, other.start, Length);
        }
 
        /// <summary>Gets an enumerator for this span.</summary>
        public Enumerator GetEnumerator() => new Enumerator(this);
 
        /// <summary>Enumerates the elements of a <see cref=""Span{T}""/>.</summary>
        public ref struct Enumerator
        {
            /// <summary>The span being enumerated.</summary>
            private readonly Span<T> _span;
            /// <summary>The next index to yield.</summary>
            private int _index;
 
            /// <summary>Initialize the enumerator.</summary>
            /// <param name=""span"">The span to enumerate.</param>
            internal Enumerator(Span<T> span)
            {
                _span = span;
                _index = -1;
            }
 
            /// <summary>Advances the enumerator to the next element of the span.</summary>
            public bool MoveNext()
            {
                int index = _index + 1;
                if (index < _span.Length)
                {
                    _index = index;
                    return true;
                }
 
                return false;
            }
 
            /// <summary>Gets the element at the current position of the enumerator.</summary>
            public ref T Current
            {
                get => ref _span[_index];
            }
        }
 
        public static implicit operator Span<T>(T[] array) => new Span<T>(array);
 
        public static implicit operator ReadOnlySpan<T>(Span<T> span) => new ReadOnlySpan<T>(span.arr);
 
        public Span<T> Slice(int offset, int length) => new Span<T>(this.arr, offset, length);
    }
 
    public readonly ref struct ReadOnlySpan<T>
    {
        private readonly T[] arr;
        private readonly int start;
 
        public ref readonly T this[int i] => ref arr[start + i];
        public override int GetHashCode() => 2;
        public int Length { get; }
        public bool IsEmpty => Length == 0;
 
        unsafe public ReadOnlySpan(void* pointer, int length)
        {
            this.arr = Helpers.ToArray<T>(pointer, length);
            this.Length = length;
        }
 
        public ReadOnlySpan(T[] arr)
        {
            this.arr = arr;
            this.Length = arr is null ? 0 : arr.Length;
        }
 
        public ReadOnlySpan(T[] arr, int start, int length)
        {
            if (start + length > arr?.Length)
            {
                throw new ArgumentOutOfRangeException();
            }
 
            this.arr = arr;
            this.start = start;
            this.Length = length;
        }
 
        public static ReadOnlySpan<T> Empty => default;
 
        public void CopyTo(Span<T> other)
        {
            Array.Copy(arr, start, other.arr, other.start, Length);
        }
 
        /// <summary>Gets an enumerator for this span.</summary>
        public Enumerator GetEnumerator() => new Enumerator(this);
 
        /// <summary>Enumerates the elements of a <see cref=""Span{T}""/>.</summary>
        public ref struct Enumerator
        {
            /// <summary>The span being enumerated.</summary>
            private readonly ReadOnlySpan<T> _span;
            /// <summary>The next index to yield.</summary>
            private int _index;
 
            /// <summary>Initialize the enumerator.</summary>
            /// <param name=""span"">The span to enumerate.</param>
            internal Enumerator(ReadOnlySpan<T> span)
            {
                _span = span;
                _index = -1;
            }
 
            /// <summary>Advances the enumerator to the next element of the span.</summary>
            public bool MoveNext()
            {
                int index = _index + 1;
                if (index < _span.Length)
                {
                    _index = index;
                    return true;
                }
 
                return false;
            }
 
            /// <summary>Gets the element at the current position of the enumerator.</summary>
            public ref readonly T Current
            {
                get => ref _span[_index];
            }
        }
 
        public static implicit operator ReadOnlySpan<T>(T[] array) => array == null ? default : new ReadOnlySpan<T>(array);
 
        // NOTE: This is defined on String in the BCL (and the target type is non-generic ReadOnlySpan<char>).
        public static implicit operator ReadOnlySpan<T>(string stringValue) => string.IsNullOrEmpty(stringValue) ? default : new ReadOnlySpan<T>((T[])(object)stringValue.ToCharArray());
 
        public ReadOnlySpan<T> Slice(int offset, int length) => new ReadOnlySpan<T>(this.arr, offset, length);
 
#nullable enable
        public static ReadOnlySpan<T> CastUp<TDerived>(ReadOnlySpan<TDerived> items) where TDerived : class?, T
        {
            return new ReadOnlySpan<T>(items.arr, items.start, items.Length);
        }
#nullable restore
    }
 
    public readonly ref struct SpanLike<T>
    {
        public readonly Span<T> field;
    }
 
    public enum Color: sbyte
    {
        Red,
        Green,
        Blue
    }
 
    public static unsafe class Helpers
    {
        public static T[] ToArray<T>(void* ptr, int count)
        {
            if (ptr == null)
            {
                return null;
            }
 
            if (typeof(T) == typeof(sbyte))
            {
                var arr = new sbyte[count];
                for(int i = 0; i < count; i++)
                {
                    arr[i] = ((sbyte*)ptr)[i];
                }
 
                return (T[])(object)arr;
            }
 
            if (typeof(T) == typeof(byte))
            {
                var arr = new byte[count];
                for(int i = 0; i < count; i++)
                {
                    arr[i] = ((byte*)ptr)[i];
                }
 
                return (T[])(object)arr;
            }
 
            if (typeof(T) == typeof(short))
            {
                var arr = new short[count];
                for(int i = 0; i < count; i++)
                {
                    arr[i] = ((short*)ptr)[i];
                }
 
                return (T[])(object)arr;
            }
 
            if (typeof(T) == typeof(ushort))
            {
                var arr = new ushort[count];
                for(int i = 0; i < count; i++)
                {
                    arr[i] = ((ushort*)ptr)[i];
                }
 
                return (T[])(object)arr;
            }
 
            if (typeof(T) == typeof(int))
            {
                var arr = new int[count];
                for(int i = 0; i < count; i++)
                {
                    arr[i] = ((int*)ptr)[i];
                }
 
                return (T[])(object)arr;
            }
 
            if (typeof(T) == typeof(uint))
            {
                var arr = new uint[count];
                for(int i = 0; i < count; i++)
                {
                    arr[i] = ((uint*)ptr)[i];
                }
 
                return (T[])(object)arr;
            }
 
            if (typeof(T) == typeof(long))
            {
                var arr = new long[count];
                for(int i = 0; i < count; i++)
                {
                    arr[i] = ((long*)ptr)[i];
                }
 
                return (T[])(object)arr;
            }
 
            if (typeof(T) == typeof(ulong))
            {
                var arr = new ulong[count];
                for(int i = 0; i < count; i++)
                {
                    arr[i] = ((ulong*)ptr)[i];
                }
 
                return (T[])(object)arr;
            }
 
            if (typeof(T) == typeof(char))
            {
                var arr = new char[count];
                for(int i = 0; i < count; i++)
                {
                    arr[i] = ((char*)ptr)[i];
                }
 
                return (T[])(object)arr;
            }
 
            if (typeof(T) == typeof(Color))
            {
                var arr = new Color[count];
                for(int i = 0; i < count; i++)
                {
                    arr[i] = ((Color*)ptr)[i];
                }
 
                return (T[])(object)arr;
            }
 
            throw new Exception(""add a case for: "" + typeof(T));
        }
    }
}";
 
        internal static readonly string Index = @"
 
namespace System
{
    using System.Runtime.CompilerServices;
    public readonly struct Index : IEquatable<Index>
    {
        private readonly int _value;
 
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public Index(int value, bool fromEnd = false)
        {
            if (value < 0)
            {
                throw new ArgumentOutOfRangeException();
            }
 
            if (fromEnd)
                _value = ~value;
            else
                _value = value;
        }
 
        // The following private constructors mainly created for perf reason to avoid the checks
        private Index(int value)
        {
            _value = value;
        }
 
        /// <summary>Create an Index pointing at first element.</summary>
        public static Index Start => new Index(0);
 
        /// <summary>Create an Index pointing at beyond last element.</summary>
        public static Index End => new Index(~0);
 
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public static Index FromStart(int value)
        {
            if (value < 0)
            {
                throw new ArgumentOutOfRangeException();
            }
 
            return new Index(value);
        }
 
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public static Index FromEnd(int value)
        {
            if (value < 0)
            {
                throw new ArgumentOutOfRangeException();
            }
 
            return new Index(~value);
        }
 
        /// <summary>Returns the index value.</summary>
        public int Value
        {
            get
            {
                if (_value < 0)
                    return ~_value;
                else
                    return _value;
            }
        }
 
        public bool IsFromEnd => _value < 0;
 
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public int GetOffset(int length)
        {
            int offset;
 
            if (IsFromEnd)
                offset = length - (~_value);
            else
                offset = _value;
 
            return offset;
        }
 
        public override bool Equals(object value) => value is Index && _value == ((Index)value)._value;
 
        public bool Equals (Index other) => _value == other._value;
 
        public override int GetHashCode() => _value;
 
        public static implicit operator Index(int value) => FromStart(value);
 
        public override string ToString() => IsFromEnd ? ""^"" + Value.ToString() : Value.ToString();
    }
}";
 
        internal static readonly string Range = @"
namespace System
{
    using System.Runtime.CompilerServices;
 
    public readonly struct Range
    {
        public Index Start { get; }
 
        public Index End { get; }
 
        public Range(Index start, Index end)
        {
            Start = start;
            End = end;
        }
 
        public static Range StartAt(Index start) => new Range(start, Index.End);
 
        public static Range EndAt(Index end) => new Range(Index.Start, end);
 
        public static Range All => new Range(Index.Start, Index.End);
 
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public OffsetAndLength GetOffsetAndLength(int length)
        {
            int start;
            Index startIndex = Start;
            if (startIndex.IsFromEnd)
                start = length - startIndex.Value;
            else
                start = startIndex.Value;
 
            int end;
            Index endIndex = End;
            if (endIndex.IsFromEnd)
                end = length - endIndex.Value;
            else
                end = endIndex.Value;
 
            if ((uint)end > (uint)length || (uint)start > (uint)end)
            {
                throw new ArgumentOutOfRangeException();
            }
 
            return new OffsetAndLength(start, end - start);
        }
 
        public readonly struct OffsetAndLength
        {
            public int Offset { get; }
            public int Length { get; }
 
            public OffsetAndLength(int offset, int length)
            {
                Offset = offset;
                Length = length;
            }
 
            public void Deconstruct(out int offset, out int length)
            {
                offset = Offset;
                length = Length;
            }
        }
 
        public override string ToString() => $""{Start}..{End}"";
    }
}";
 
        public static readonly string GetSubArray = @"
namespace System.Runtime.CompilerServices
{
    public static class RuntimeHelpers
    {
        public static T[] GetSubArray<T>(T[] array, Range range)
        {
            Type elementType = array.GetType().GetElementType();
            var (offset, length) = range.GetOffsetAndLength(array.Length);
 
            T[] newArray = (T[])Array.CreateInstance(elementType, length);
            Array.Copy(array, offset, newArray, 0, length);
            return newArray;
        }
    }
}";
 
        public static readonly string ITuple = @"
namespace System.Runtime.CompilerServices
{
    public interface ITuple
    {
        int Length { get; }
        object this[int index] { get; }
    }
}";
 
        public static readonly string MemoryExtensions = @"
namespace System
{
    public static class MemoryExtensions
    {
        public static bool SequenceEqual<T> (this ReadOnlySpan<T> span, ReadOnlySpan<T> other) where T : IEquatable<T>
        {
            // unoptimized implementation for testing purposes
            if (span.Length != other.Length) return false;
            for(var i = 0; i < span.Length; i++)
            {
                if (!span[i].Equals(other[i]))
                    return false;
            }
            return true;
        }
 
        public static bool SequenceEqual<T> (this Span<T> span, ReadOnlySpan<T> other) where T : IEquatable<T>
        {
            // unoptimized implementation for testing purposes
            if (span.Length != other.Length) return false;
            for(var i = 0; i < span.Length; i++)
            {
                if (!span[i].Equals(other[i]))
                    return false;
            }
            return true;
        }
 
        public static ReadOnlySpan<char> AsSpan(this string text) => string.IsNullOrEmpty(text) ? default : new ReadOnlySpan<char>(text.ToCharArray());
 
        public static Span<T> AsSpan<T>(this T[] array) => new Span<T>(array);
    }
}";
    }
}