Update the types consumers of Index and Range (#24036)
authorTarek Mahmoud Sayed <tarekms@microsoft.com>
Wed, 17 Apr 2019 16:54:51 +0000 (17:54 +0100)
committerGitHub <noreply@github.com>
Wed, 17 Apr 2019 16:54:51 +0000 (17:54 +0100)
* Update the types consumers of Index and Range

The C# compiler now can automatically support the indexers with Index and Range parameters on any type meet the conditions:
- The type exposes Length or Count property which returning integer.
- The type has indexer of integer parameter.
- The type has a Slice method which takes 2 integers

The change here is to remove the methods and indexers of the types which we previously added it as the compiler will automatically provide those.

* Remove the JIT failing test

src/System.Private.CoreLib/shared/System/Memory.cs
src/System.Private.CoreLib/shared/System/ReadOnlyMemory.cs
src/System.Private.CoreLib/shared/System/ReadOnlySpan.Fast.cs
src/System.Private.CoreLib/shared/System/Span.Fast.cs
src/System.Private.CoreLib/shared/System/String.Manipulation.cs
src/System.Private.CoreLib/shared/System/String.cs
src/System.Private.CoreLib/src/System/Utf8String.Manipulation.cs
src/System.Private.CoreLib/src/System/Utf8String.cs
tests/src/JIT/Regression/JitBlue/GitHub_20958/GitHub_20958.cs [deleted file]
tests/src/JIT/Regression/JitBlue/GitHub_20958/GitHub_20958.csproj [deleted file]

index e61ada7..e3d0347 100644 (file)
@@ -282,35 +282,6 @@ namespace System
         }
 
         /// <summary>
-        /// Forms a slice out of the given memory, beginning at 'startIndex'
-        /// </summary>
-        /// <param name="startIndex">The index at which to begin this slice.</param>
-        [MethodImpl(MethodImplOptions.AggressiveInlining)]
-        public Memory<T> Slice(Index startIndex)
-        {
-            int actualIndex = startIndex.GetOffset(_length);
-            return Slice(actualIndex);
-        }
-
-        /// <summary>
-        /// Forms a slice out of the given memory using the range start and end indexes.
-        /// </summary>
-        /// <param name="range">The range used to slice the memory using its start and end indexes.</param>
-        [MethodImpl(MethodImplOptions.AggressiveInlining)]
-        public Memory<T> Slice(Range range)
-        {
-            (int start, int length) = range.GetOffsetAndLength(_length);
-            // It is expected for _index + start to be negative if the memory is already pre-pinned.
-            return new Memory<T>(_object, _index + start, length);
-        }
-
-        /// <summary>
-        /// Forms a slice out of the given memory using the range start and end indexes.
-        /// </summary>
-        /// <param name="range">The range used to slice the memory using its start and end indexes.</param>
-        public Memory<T> this[Range range] => Slice(range);
-
-        /// <summary>
         /// Returns a span from the memory.
         /// </summary>
         public unsafe Span<T> Span
index b7814cf..67c85eb 100644 (file)
@@ -211,35 +211,6 @@ namespace System
         }
 
         /// <summary>
-        /// Forms a slice out of the given memory, beginning at 'startIndex'
-        /// </summary>
-        /// <param name="startIndex">The index at which to begin this slice.</param>
-        [MethodImpl(MethodImplOptions.AggressiveInlining)]
-        public ReadOnlyMemory<T> Slice(Index startIndex)
-        {
-            int actualIndex = startIndex.GetOffset(_length);
-            return Slice(actualIndex);
-        }
-
-        /// <summary>
-        /// Forms a slice out of the given memory using the range start and end indexes.
-        /// </summary>
-        /// <param name="range">The range used to slice the memory using its start and end indexes.</param>
-        [MethodImpl(MethodImplOptions.AggressiveInlining)]
-        public ReadOnlyMemory<T> Slice(Range range)
-        {
-            (int start, int length) = range.GetOffsetAndLength(_length);
-            // It is expected for _index + start to be negative if the memory is already pre-pinned.
-            return new ReadOnlyMemory<T>(_object, _index + start, length);
-        }
-
-        /// <summary>
-        /// Forms a slice out of the given memory using the range start and end indexes.
-        /// </summary>
-        /// <param name="range">The range used to slice the memory using its start and end indexes.</param>
-        public ReadOnlyMemory<T> this[Range range] => Slice(range);
-
-        /// <summary>
         /// Returns a span from the memory.
         /// </summary>
         public unsafe ReadOnlySpan<T> Span
index 00337a5..df49337 100644 (file)
@@ -153,18 +153,6 @@ namespace System
 #endif
         }
 
-        public ref readonly T this[Index index]
-        {
-            get
-            {
-                // Evaluate the actual index first because it helps performance
-                int actualIndex = index.GetOffset(_length);
-                return ref this [actualIndex];
-            }
-        }
-
-        public ReadOnlySpan<T> this[Range range] => Slice(range);
-
         /// <summary>
         /// Returns a reference to the 0th element of the Span. If the Span is empty, returns null reference.
         /// It can be used for pinning and is required to support the use of span within a fixed statement.
@@ -293,33 +281,6 @@ namespace System
         }
 
         /// <summary>
-        /// Forms a slice out of the given read-only span, beginning at 'startIndex'
-        /// </summary>
-        /// <param name="startIndex">The index at which to begin this slice.</param>
-        [MethodImpl(MethodImplOptions.AggressiveInlining)]
-        public ReadOnlySpan<T> Slice(Index startIndex)
-        {
-            int actualIndex;
-            if (startIndex.IsFromEnd)
-                actualIndex = _length - startIndex.Value;
-            else
-                actualIndex = startIndex.Value;
-
-            return Slice(actualIndex);
-        }
-
-        /// <summary>
-        /// Forms a slice out of the given read-only span, beginning at range start index to the range end
-        /// </summary>
-        /// <param name="range">The range which has the start and end indexes used to slice the span.</param>
-        [MethodImpl(MethodImplOptions.AggressiveInlining)]
-        public ReadOnlySpan<T> Slice(Range range)
-        {
-            (int start, int length) = range.GetOffsetAndLength(_length);
-            return new ReadOnlySpan<T>(ref Unsafe.Add(ref _pointer.Value, start), length);
-        }
-
-        /// <summary>
         /// Copies the contents of this read-only span into a new array.  This heap
         /// allocates, so should generally be avoided, however it is sometimes
         /// necessary to bridge the gap with APIs written in terms of arrays.
index adc1f39..c884989 100644 (file)
@@ -159,18 +159,6 @@ namespace System
 #endif
         }
 
-        public ref T this[Index index]
-        {
-            get
-            {
-                // Evaluate the actual index first because it helps performance
-                int actualIndex = index.GetOffset(_length);
-                return ref this [actualIndex];
-            }
-        }
-
-        public Span<T> this[Range range] => Slice(range);
-
         /// <summary>
         /// Returns a reference to the 0th element of the Span. If the Span is empty, returns null reference.
         /// It can be used for pinning and is required to support the use of span within a fixed statement.
@@ -377,28 +365,6 @@ namespace System
         }
 
         /// <summary>
-        /// Forms a slice out of the given span, beginning at 'startIndex'
-        /// </summary>
-        /// <param name="startIndex">The index at which to begin this slice.</param>
-        [MethodImpl(MethodImplOptions.AggressiveInlining)]
-        public Span<T> Slice(Index startIndex)
-        {
-            int actualIndex = startIndex.GetOffset(_length);
-            return Slice(actualIndex);
-        }
-
-        /// <summary>
-        /// Forms a slice out of the given span, beginning at range start index to the range end
-        /// </summary>
-        /// <param name="range">The range which has the start and end indexes used to slice the span.</param>
-        [MethodImpl(MethodImplOptions.AggressiveInlining)]
-        public Span<T> Slice(Range range)
-        {
-            (int start, int length) = range.GetOffsetAndLength(_length);
-            return new Span<T>(ref Unsafe.Add(ref _pointer.Value, start), length);
-        }
-
-        /// <summary>
         /// Copies the contents of this span into a new array.  This heap
         /// allocates, so should generally be avoided, however it is sometimes
         /// necessary to bridge the gap with APIs written in terms of arrays.
index dc7f015..278a3b6 100644 (file)
@@ -1680,20 +1680,6 @@ namespace System
             return InternalSubString(startIndex, length);
         }
 
-        [MethodImpl(MethodImplOptions.AggressiveInlining)]
-        public string Substring(Index startIndex)
-        {
-            int actualIndex = startIndex.GetOffset(Length);
-            return Substring(actualIndex);
-        }
-
-        [MethodImpl(MethodImplOptions.AggressiveInlining)]
-        public string Substring(Range range)
-        {
-            (int start, int length) = range.GetOffsetAndLength(Length);
-            return Substring(start, length);
-        }
-
         private unsafe string InternalSubString(int startIndex, int length)
         {
             Debug.Assert(startIndex >= 0 && startIndex <= this.Length, "StartIndex is out of range!");
index 3ae88bb..3701434 100644 (file)
@@ -448,19 +448,6 @@ namespace System
             return (value == null || 0u >= (uint)value.Length) ? true : false;
         }
 
-        [System.Runtime.CompilerServices.IndexerName("Chars")]
-        public char this[Index index]
-        {
-            get
-            {
-                int actualIndex = index.GetOffset(Length);
-                return this[actualIndex];
-            }
-        }
-
-        [System.Runtime.CompilerServices.IndexerName("Chars")]
-        public string this[Range range] => Substring(range);
-
         public static bool IsNullOrWhiteSpace(string? value)
         {
             if (value == null) return true;
index 9ca72f1..6fcdf17 100644 (file)
@@ -76,12 +76,12 @@ namespace System
             return InternalSubstring(startIndex, length);
         }
 
+        // Slice intended to be used by the compiler only to provide indexer with range parameter functionality.
+        // Developers should be using Substring method instead.
         [MethodImpl(MethodImplOptions.AggressiveInlining)]
-        public Utf8String Substring(Range range)
-        {
-            (int start, int length) = range.GetOffsetAndLength(Length);
-            return Substring(start, length);
-        }
+        [ComponentModel.EditorBrowsable(ComponentModel.EditorBrowsableState.Never)]
+        public Utf8String Slice(int startIndex, int length) => Substring(startIndex, length);
+
 
         [StackTraceHidden]
         [MethodImpl(MethodImplOptions.AggressiveInlining)]
index 8551830..f488c9b 100644 (file)
@@ -84,25 +84,6 @@ namespace System
             }
         }
 
-        /// <summary>
-        /// Gets the <see cref="Char8"/> at the specified position.
-        /// </summary>
-        public Char8 this[Index index]
-        {
-            get
-            {
-                // Just like String, we don't allow indexing into the null terminator itself.
-
-                int actualIndex = index.GetOffset(Length);
-                return this[actualIndex];
-            }
-        }
-
-        /// <summary>
-        /// Gets a substring of this <see cref="Utf8String"/> based on the provided <paramref name="range"/>.
-        /// </summary>
-        public Utf8String this[Range range] => Substring(range);
-
         /*
          * METHODS
          */
diff --git a/tests/src/JIT/Regression/JitBlue/GitHub_20958/GitHub_20958.cs b/tests/src/JIT/Regression/JitBlue/GitHub_20958/GitHub_20958.cs
deleted file mode 100644 (file)
index 45730f5..0000000
+++ /dev/null
@@ -1,61 +0,0 @@
-// 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.
-
-using System;
-
-// This test was extracted from the Indexer tests in the corefx System.Memory.Tests.
-// The JIT was trying to expand the form of indexer that takes a range, but was not
-// correctly expanding it, as it was expecting only the scalar index form.
-
-public class GitHub_20958
-{
-
-    public static int IndexerWithRangeTest()
-    {
-        int returnVal = 100;
-
-        ReadOnlySpan<char> span = "Hello".AsSpan();
-        ReadOnlySpan<char> sliced = span[new Range(new Index(1, fromEnd: false), new Index(1, fromEnd: true))];
-        if (span.Slice(1, 3) != sliced)
-        {
-            returnVal = -1;
-        }
-        try
-        {
-            ReadOnlySpan<char> s = "Hello".AsSpan()[new Range(new Index(1, fromEnd: true), new Index(1, fromEnd: false))];
-            returnVal = -1;
-        }
-        catch (ArgumentOutOfRangeException)
-        {
-        }
-        catch (Exception e)
-        {
-            returnVal = -1;
-        }
-        Span<char> span1 = new Span<char>(new char[] { 'H', 'e', 'l', 'l', 'o' });
-        Span<char> sliced1 = span1[new Range(new Index(2, fromEnd: false), new Index(1, fromEnd: true))];
-        if (span1.Slice(2, 2) != sliced1)
-        {
-            returnVal = -1;
-        }
-        try
-        {
-            Span<char> s = new Span<char>(new char[] { 'H', 'i' })[new Range(new Index(0, fromEnd: true), new Index(1, fromEnd: false))];
-            returnVal = -1;
-        }
-        catch (ArgumentOutOfRangeException)
-        {
-        }
-        catch (Exception e)
-        {
-            returnVal = -1;
-        }
-        return returnVal;
-    }
-
-    public static int Main()
-    {
-        return IndexerWithRangeTest();
-    }
-}
diff --git a/tests/src/JIT/Regression/JitBlue/GitHub_20958/GitHub_20958.csproj b/tests/src/JIT/Regression/JitBlue/GitHub_20958/GitHub_20958.csproj
deleted file mode 100644 (file)
index d86ed9f..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
-  <PropertyGroup>
-    <Configuration Condition=" '$(Configuration)' == '' ">Release</Configuration>
-    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
-    <AssemblyName>$(MSBuildProjectName)</AssemblyName>
-    <OutputType>Exe</OutputType>
-    <DebugType></DebugType>
-    <Optimize>True</Optimize>
-  </PropertyGroup>
-  <ItemGroup>
-    <Compile Include="$(MSBuildProjectName).cs" />
-  </ItemGroup>
-  <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
-  <PropertyGroup Condition=" '$(MsBuildProjectDirOverride)' != '' "></PropertyGroup>
-</Project>
\ No newline at end of file