Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make the CharSequence wrappers in Predef non-implicit, for JDK 15 #9292

Merged
merged 1 commit into from Nov 4, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
19 changes: 13 additions & 6 deletions src/library/scala/Predef.scala
Expand Up @@ -87,9 +87,9 @@ import scala.annotation.meta.{ companionClass, companionMethod }
* @groupprio implicit-classes-any 70
* @groupdesc implicit-classes-any These implicit classes add useful extension methods to every type.
*
* @groupname implicit-classes-char CharSequence Conversions
* @groupprio implicit-classes-char 80
* @groupdesc implicit-classes-char These implicit classes add CharSequence methods to Array[Char] and IndexedSeq[Char] instances.
* @groupname char-sequence-wrappers CharSequence Wrappers
* @groupprio char-sequence-wrappers 80
* @groupdesc char-sequence-wrappers Wrappers that implements CharSequence and were implicit classes.
*
* @groupname conversions-java-to-anyval Java to Scala
* @groupprio conversions-java-to-anyval 90
Expand Down Expand Up @@ -380,21 +380,28 @@ object Predef extends LowPriorityImplicits {
def +(other: String): String = String.valueOf(self) + other
}

implicit final class SeqCharSequence(sequenceOfChars: scala.collection.IndexedSeq[Char]) extends CharSequence {
/** @group char-sequence-wrappers */
final class SeqCharSequence(sequenceOfChars: scala.collection.IndexedSeq[Char]) extends CharSequence {
def length: Int = sequenceOfChars.length
def charAt(index: Int): Char = sequenceOfChars(index)
def subSequence(start: Int, end: Int): CharSequence = new SeqCharSequence(sequenceOfChars.slice(start, end))
override def toString = sequenceOfChars.mkString
}

/** @group implicit-classes-char */
implicit final class ArrayCharSequence(arrayOfChars: Array[Char]) extends CharSequence {
/** @group char-sequence-wrappers */
def SeqCharSequence(sequenceOfChars: scala.collection.IndexedSeq[Char]): SeqCharSequence = new SeqCharSequence(sequenceOfChars)

/** @group char-sequence-wrappers */
final class ArrayCharSequence(arrayOfChars: Array[Char]) extends CharSequence {
def length: Int = arrayOfChars.length
def charAt(index: Int): Char = arrayOfChars(index)
def subSequence(start: Int, end: Int): CharSequence = new runtime.ArrayCharSequence(arrayOfChars, start, end)
override def toString = arrayOfChars.mkString
}

/** @group char-sequence-wrappers */
def ArrayCharSequence(arrayOfChars: Array[Char]): ArrayCharSequence = new ArrayCharSequence(arrayOfChars)

/** @group conversions-string */
@inline implicit def augmentString(x: String): StringOps = new StringOps(x)

Expand Down
10 changes: 8 additions & 2 deletions src/library/scala/collection/mutable/StringBuilder.scala
Expand Up @@ -12,8 +12,6 @@

package scala.collection.mutable

import java.lang.String

import scala.collection.{IterableFactoryDefaults, IterableOnce}
import scala.collection.immutable.WrappedString

Expand Down Expand Up @@ -468,6 +466,14 @@ final class StringBuilder(val underlying: java.lang.StringBuilder) extends Abstr
* @return the last applicable index where target occurs, or -1 if not found.
*/
def lastIndexOf(str: String, fromIndex: Int): Int = underlying.lastIndexOf(str, fromIndex)

/** Tests whether this builder is empty.
*
* This method is required for JDK15+ compatibility
*
* @return `true` if this builder contains nothing, `false` otherwise.
*/
override def isEmpty: Boolean = underlying.length() == 0
}

object StringBuilder {
Expand Down
10 changes: 8 additions & 2 deletions src/reflect/scala/reflect/internal/Names.scala
Expand Up @@ -187,12 +187,17 @@ trait Names extends api.Names {

// Classes ----------------------------------------------------------------------

// Dummy trait to make Name#isEmpty with override keyword at JDK before 15
sealed trait NameHasIsEmpty {
def isEmpty: Boolean
}

/** The name class.
* TODO - resolve schizophrenia regarding whether to treat Names as Strings
* or Strings as Names. Give names the key functions the absence of which
* make people want Strings all the time.
*/
sealed abstract class Name(protected val index: Int, protected val len: Int, protected val cachedString: String) extends NameApi with CharSequence {
sealed abstract class Name(protected val index: Int, protected val len: Int, protected val cachedString: String) extends NameApi with NameHasIsEmpty with CharSequence {
type ThisNameType >: Null <: Name
protected[this] def thisName: ThisNameType

Expand All @@ -208,8 +213,9 @@ trait Names extends api.Names {

/** The length of this name. */
final def length: Int = len
final def isEmpty = length == 0
final def nonEmpty = !isEmpty
// This method is implements NameHasIsEmpty, and overrides CharSequence's isEmpty on JDK 15+
override final def isEmpty = length == 0

def nameKind: String
def isTermName: Boolean
Expand Down
23 changes: 22 additions & 1 deletion test/junit/scala/ArrayTest.scala
@@ -1,6 +1,6 @@
package scala

import org.junit.Assert.assertArrayEquals
import org.junit.Assert.{ assertArrayEquals, assertFalse, assertTrue }
import org.junit.Test

import scala.runtime.BoxedUnit
Expand All @@ -13,4 +13,25 @@ class ArrayTest {
assertArrayEquals(expected, Array.copyAs[Unit](Array[Nothing](), 32).asInstanceOf[Array[AnyRef]])
assertArrayEquals(expected, Array.copyAs[Unit](Array[Unit](), 32).asInstanceOf[Array[AnyRef]])
}

@Test
def testArrayIsEmpty(): Unit = {
assertTrue(Array[Int]().isEmpty)
assertTrue(Array[Char]().isEmpty) // scala/bug#12172
assertTrue(Array[String]().isEmpty)

assertFalse(Array(1).isEmpty)
assertFalse(Array[Char](1).isEmpty)
assertFalse(Array("").isEmpty)

def ge[T](a: Array[T]) = a.isEmpty

assertTrue(ge(Array[Int]()))
assertTrue(ge(Array[Char]()))
assertTrue(ge(Array[String]()))

assertFalse(ge(Array(1)))
assertFalse(ge(Array[Char]('x')))
assertFalse(ge(Array("")))
}
}
16 changes: 0 additions & 16 deletions test/junit/scala/CharSequenceImplicitsTests.scala

This file was deleted.