Skip to content

Commit

Permalink
Merge pull request #9292 from dwijnand/non-implicit-enrich-CharSequence
Browse files Browse the repository at this point in the history
Make the CharSequence wrappers in Predef non-implicit, for JDK 15
  • Loading branch information
dwijnand committed Nov 4, 2020
2 parents decbd53 + 0230f94 commit 7101549
Show file tree
Hide file tree
Showing 5 changed files with 51 additions and 27 deletions.
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.

0 comments on commit 7101549

Please sign in to comment.