Skip to content

Provide compatibility with current Scala 2.12.x (close to RC1) #76

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

Merged
merged 1 commit into from
Aug 31, 2016
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -41,13 +41,13 @@ object PrimitiveIteratorConverters {
/** Packages a `scala.collection.Iterator[Double]` as a `java.util.PrimitiveIterator.OfDouble` */
def fromScala(it: Iterator[Double]): PrimitiveIterator.OfDouble = new PrimitiveIterator.OfDouble {
def hasNext = it.hasNext
def next() = it.next()
override def next() = it.next().asInstanceOf[java.lang.Double]
def nextDouble() = it.next()
def remove() { throw new UnsupportedOperationException("remove on scala.collection.Iterator") }
def forEachRemaining(c: java.util.function.Consumer[_ >: java.lang.Double]) {
override def remove() { throw new UnsupportedOperationException("remove on scala.collection.Iterator") }
override def forEachRemaining(c: java.util.function.Consumer[_ >: java.lang.Double]) {
while (it.hasNext) c.accept(it.next)
}
def forEachRemaining(c: java.util.function.DoubleConsumer) {
override def forEachRemaining(c: java.util.function.DoubleConsumer) {
while (it.hasNext) c.accept(it.next)
}
}
Expand All @@ -62,13 +62,13 @@ object PrimitiveIteratorConverters {
/** Packages a `scala.collection.Iterator[Int]` as a `java.util.PrimitiveIterator.OfInt` */
def fromScala(it: Iterator[Int]): PrimitiveIterator.OfInt = new PrimitiveIterator.OfInt {
def hasNext = it.hasNext
def next() = it.next()
override def next() = it.next().asInstanceOf[java.lang.Integer]
def nextInt() = it.next()
def remove() { throw new UnsupportedOperationException("remove on scala.collection.Iterator") }
def forEachRemaining(c: java.util.function.Consumer[_ >: java.lang.Integer]) {
override def remove() { throw new UnsupportedOperationException("remove on scala.collection.Iterator") }
override def forEachRemaining(c: java.util.function.Consumer[_ >: java.lang.Integer]) {
while (it.hasNext) c.accept(it.next)
}
def forEachRemaining(c: java.util.function.IntConsumer) {
override def forEachRemaining(c: java.util.function.IntConsumer) {
while (it.hasNext) c.accept(it.next)
}
}
Expand All @@ -83,13 +83,13 @@ object PrimitiveIteratorConverters {
/** Packages a `scala.collection.Iterator[Long]` as a `java.util.PrimitiveIterator.OfLong` */
def fromScala(it: Iterator[Long]): PrimitiveIterator.OfLong = new PrimitiveIterator.OfLong {
def hasNext = it.hasNext
def next() = it.next()
override def next() = it.next().asInstanceOf[java.lang.Long]
def nextLong() = it.next()
def remove() { throw new UnsupportedOperationException("remove on scala.collection.Iterator") }
def forEachRemaining(c: java.util.function.Consumer[_ >: java.lang.Long]) {
override def remove() { throw new UnsupportedOperationException("remove on scala.collection.Iterator") }
override def forEachRemaining(c: java.util.function.Consumer[_ >: java.lang.Long]) {
while (it.hasNext) c.accept(it.next)
}
def forEachRemaining(c: java.util.function.LongConsumer) {
override def forEachRemaining(c: java.util.function.LongConsumer) {
while (it.hasNext) c.accept(it.next)
}
}
Expand Down
20 changes: 10 additions & 10 deletions src/main/scala/scala/compat/java8/collectionImpl/Stepper.scala
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,7 @@ private[collectionImpl] class ProxySpliteratorViaTry[A](underlying: TryStepper[A

/** Any `AnyStepper` combines the functionality of a Java `Iterator`, a Java `Spliterator`, and a `Stepper`. */
trait AnyStepper[A] extends Stepper[A] with java.util.Iterator[A] with Spliterator[A] with StepperLike[A, AnyStepper[A]] {
def forEachRemaining(c: java.util.function.Consumer[_ >: A]) { while (hasNext) { c.accept(next) } }
override def forEachRemaining(c: java.util.function.Consumer[_ >: A]) { while (hasNext) { c.accept(next) } }
def hasStep = hasNext()
def knownSize = getExactSizeIfKnown
def nextStep = next
Expand Down Expand Up @@ -267,12 +267,12 @@ private[collectionImpl] object AnyStepper {

/** A `DoubleStepper` combines the functionality of a Java `PrimitiveIterator`, a Java `Spliterator`, and a `Stepper`, all specialized for `Double` values. */
trait DoubleStepper extends Stepper[Double] with java.util.PrimitiveIterator.OfDouble with Spliterator.OfDouble with StepperLike[Double, DoubleStepper] {
def forEachRemaining(c: java.util.function.Consumer[_ >: java.lang.Double]) { while (hasNext) { c.accept(java.lang.Double.valueOf(nextDouble)) } }
def forEachRemaining(c: java.util.function.DoubleConsumer) { while (hasNext) { c.accept(nextDouble) } }
override def forEachRemaining(c: java.util.function.Consumer[_ >: java.lang.Double]) { while (hasNext) { c.accept(java.lang.Double.valueOf(nextDouble)) } }
override def forEachRemaining(c: java.util.function.DoubleConsumer) { while (hasNext) { c.accept(nextDouble) } }
def hasStep = hasNext()
def knownSize = getExactSizeIfKnown
def nextStep = nextDouble
def tryAdvance(c: java.util.function.Consumer[_ >: java.lang.Double]): Boolean = if (hasNext) { c.accept(java.lang.Double.valueOf(nextDouble)); true } else false
override def tryAdvance(c: java.util.function.Consumer[_ >: java.lang.Double]): Boolean = if (hasNext) { c.accept(java.lang.Double.valueOf(nextDouble)); true } else false
def tryAdvance(c: java.util.function.DoubleConsumer): Boolean = if (hasNext) { c.accept(nextDouble); true } else false
def tryStep(f: Double => Unit): Boolean = if (hasNext) { f(nextDouble); true } else false
def trySplit() = substep
Expand All @@ -283,12 +283,12 @@ trait DoubleStepper extends Stepper[Double] with java.util.PrimitiveIterator.OfD

/** An `IntStepper` combines the functionality of a Java `PrimitiveIterator`, a Java `Spliterator`, and a `Stepper`, all specialized for `Int` values. */
trait IntStepper extends Stepper[Int] with java.util.PrimitiveIterator.OfInt with Spliterator.OfInt with StepperLike[Int, IntStepper] {
def forEachRemaining(c: java.util.function.Consumer[_ >: java.lang.Integer]) { while (hasNext) { c.accept(java.lang.Integer.valueOf(nextInt)) } }
def forEachRemaining(c: java.util.function.IntConsumer) { while (hasNext) { c.accept(nextInt) } }
override def forEachRemaining(c: java.util.function.Consumer[_ >: java.lang.Integer]) { while (hasNext) { c.accept(java.lang.Integer.valueOf(nextInt)) } }
override def forEachRemaining(c: java.util.function.IntConsumer) { while (hasNext) { c.accept(nextInt) } }
def hasStep = hasNext()
def knownSize = getExactSizeIfKnown
def nextStep = nextInt
def tryAdvance(c: java.util.function.Consumer[_ >: java.lang.Integer]): Boolean = if (hasNext) { c.accept(java.lang.Integer.valueOf(nextInt)); true } else false
override def tryAdvance(c: java.util.function.Consumer[_ >: java.lang.Integer]): Boolean = if (hasNext) { c.accept(java.lang.Integer.valueOf(nextInt)); true } else false
def tryAdvance(c: java.util.function.IntConsumer): Boolean = if (hasNext) { c.accept(nextInt); true } else false
def tryStep(f: Int => Unit): Boolean = if (hasNext) { f(nextInt); true } else false
def trySplit() = substep
Expand All @@ -299,12 +299,12 @@ trait IntStepper extends Stepper[Int] with java.util.PrimitiveIterator.OfInt wit

/** A `LongStepper` combines the functionality of a Java `PrimitiveIterator`, a Java `Spliterator`, and a `Stepper`, all specialized for `Long` values. */
trait LongStepper extends Stepper[Long] with java.util.PrimitiveIterator.OfLong with Spliterator.OfLong with StepperLike[Long, LongStepper] {
def forEachRemaining(c: java.util.function.Consumer[_ >: java.lang.Long]) { while (hasNext) { c.accept(java.lang.Long.valueOf(nextLong)) } }
def forEachRemaining(c: java.util.function.LongConsumer) { while (hasNext) { c.accept(nextLong) } }
override def forEachRemaining(c: java.util.function.Consumer[_ >: java.lang.Long]) { while (hasNext) { c.accept(java.lang.Long.valueOf(nextLong)) } }
override def forEachRemaining(c: java.util.function.LongConsumer) { while (hasNext) { c.accept(nextLong) } }
def hasStep = hasNext()
def knownSize = getExactSizeIfKnown
def nextStep = nextLong
def tryAdvance(c: java.util.function.Consumer[_ >: java.lang.Long]): Boolean = if (hasNext) { c.accept(java.lang.Long.valueOf(nextLong)); true } else false
override def tryAdvance(c: java.util.function.Consumer[_ >: java.lang.Long]): Boolean = if (hasNext) { c.accept(java.lang.Long.valueOf(nextLong)); true } else false
def tryAdvance(c: java.util.function.LongConsumer): Boolean = if (hasNext) { c.accept(nextLong); true } else false
def tryStep(f: Long => Unit): Boolean = if (hasNext) { f(nextLong); true } else false
def trySplit() = substep
Expand Down
4 changes: 2 additions & 2 deletions src/test/java/scala/runtime/java8/BoxingTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
public class BoxingTest {
@Test
public void nullBoxesInterpretedAsZeroF1() {
JFunction1 jFunction1 = new JFunction1$mcII$sp() {
JFunction1$mcII$sp jFunction1 = new JFunction1$mcII$sp() {
@Override
public int apply$mcII$sp(int v1) {
return v1 + 1;
Expand All @@ -20,7 +20,7 @@ public void nullBoxesInterpretedAsZeroF1() {

@Test
public void nullBoxesInterpretedAsZeroF2() {
JFunction2 jFunction2 = new JFunction2$mcIII$sp() {
JFunction2$mcIII$sp jFunction2 = new JFunction2$mcIII$sp() {
@Override
public int apply$mcIII$sp(int v1, int v2) {
return v1 + v2 + 1;
Expand Down
79 changes: 30 additions & 49 deletions src/test/java/scala/runtime/java8/LambdaTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,32 +7,20 @@
import scala.runtime.*;

import static junit.framework.Assert.assertEquals;
import static scala.runtime.java8.JFunction.*;
import static scala.runtime.java8.TestAPI.*;

import org.junit.Test;


public class LambdaTest {
/*
// This version is for Scala 2.12.0-RC1 and is not compatible with 2.11. It's commented out to allow cross-building.
@Test
public void lambdaDemo() {
// Not allowed with Scala 2.10 nor 2.11
// "incompatible types: Function1 is not a functional interface"
// scala.Function1<String, String> f = (String s) -> s;

// Function1 is not a functional interface because it has abstract
// methods in addition to apply, namely `compose` and `andThen`
// (which are implemented in Scala-derived subclasses with mixin
// inheritance), and the specialized variants of apply (also provided
// by scalac.)

// That's a pity, but we can get pretty close with this library!

// We have to tell javac to use `JFunction1` as the functional interface.
JFunction1<String, String> f1 = (String s) -> s;
scala.Function1<String, String> f1 = (String s) -> s;

// That's more or less equivalent to the old, anonymous class syntax:
new JFunction1<String, String>() {
new scala.Function1<String, String>() {
public String apply(String s) { return s; }
};

Expand All @@ -47,80 +35,73 @@ public void lambdaDemo() {
// F1 is a subclass of Function1:
scala.Function1<String, String> f2 = f1;

// Factory methods in `JFunction` can reduce the verbosity a little:
// `func` is actually just an identity method; it only exists to
// trigger lambda creation using the `JFunction1` functional interface.
scala.Function1<String, String> f3 = func((String s) -> s);

// Note that javac's type inference can infer the parameter type here,
// based on the acribed type of `f4`.
scala.Function1<String, String> f4 = func(s -> s);

// f1.apply("");
scala.Function1<String, String> f3 = (String s) -> s;
scala.Function1<String, String> f4 = s -> s;

// Specialized variants of the `apply` method are implenented in the
// functional interface
JFunction1<Integer, Integer> f5 = (i) -> -i;
scala.Function1<Integer, Integer> f5 = (i -> -i);
assert(f5.apply(1) == -1);
assert(f5.apply$mcII$sp(1) == -1);

// as are `curried`, `tupled`, `compose`, `andThen`.
f3.compose(f3).andThen(f3).apply("");
scala.Function2<String, String, String> f6 = func((s1, s2) -> join(s1, s2));
scala.Function2<String, String, String> f6 = ((s1, s2) -> join(s1, s2));
assert(f6.curried().apply("1").apply("2").equals("12"));

// Functions returning unit must use the `JProcedure1`, ... functional interfaces
// in order to convert a void lamdba return to Scala's Unit.
//
// The easiest way to do this is via `JFunction.proc`, ....
// Functions returning unit must return BoxedUnit.UNIT explicitly.
//
// Note that the lambda has a return type of `void` if the last
// statement is a call to a `void` returning method, or if it is
// a `return`.
scala.Function1<String, BoxedUnit> f7 = proc(s -> sideEffect());
scala.Function1<String, BoxedUnit> f8 = proc(s -> {s.toUpperCase(); return;});
scala.Function1<String, BoxedUnit> f7 = (s -> { sideEffect(); return scala.runtime.BoxedUnit.UNIT; });
scala.Function1<String, BoxedUnit> f8 = (s -> { s.toUpperCase(); return scala.runtime.BoxedUnit.UNIT; });

// Function0 is also available
scala.Function0<String> f9 = func(() -> "42");
scala.Function0<String> f9 = (() -> "42");
assert(f9.apply().equals("42"));

// You can go up to 22 (the highest arity function defined in the Scala standard library.)
assert(acceptFunction1(func(v1 -> v1.toUpperCase())).equals("1"));
acceptFunction1Unit(proc(v1 -> sideEffect()));
acceptFunction1Unit(proc(v1 -> {v1.toUpperCase(); return;}));
assert(acceptFunction1((v1 -> v1.toUpperCase())).equals("1"));
acceptFunction1Unit((v1 -> {sideEffect(); return scala.runtime.BoxedUnit.UNIT;}));
acceptFunction1Unit((v1 -> {v1.toUpperCase(); return scala.runtime.BoxedUnit.UNIT;}));

assert(acceptFunction2(func((v1, v2) -> join(v1, v2))).equals("12"));
acceptFunction2Unit(proc((v1, v2) -> {v1.toUpperCase(); return;}));
assert(acceptFunction2(((v1, v2) -> join(v1, v2))).equals("12"));
acceptFunction2Unit(((v1, v2) -> {v1.toUpperCase(); return scala.runtime.BoxedUnit.UNIT;}));

assert(acceptFunction3(func((v1, v2, v3) -> join(v1, v2, v3))).equals("123"));
acceptFunction3Unit(proc((v1, v2, v3) -> {v1.toUpperCase(); return;}));
assert(acceptFunction3(((v1, v2, v3) -> join(v1, v2, v3))).equals("123"));
acceptFunction3Unit(((v1, v2, v3) -> {v1.toUpperCase(); return scala.runtime.BoxedUnit.UNIT;}));

assert(acceptFunction22(func((v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22) -> join(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22))).equals("12345678910111213141516171819202122"));
acceptFunction22Unit( proc((v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22) -> {v1.toUpperCase(); return;}));
assert(acceptFunction22(((v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22) -> join(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22))).equals("12345678910111213141516171819202122"));
acceptFunction22Unit( ((v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22) -> {v1.toUpperCase(); return scala.runtime.BoxedUnit.UNIT;}));
}
*/

/*
// The JFunctions in 2.12.0-M4 are not Serializable anymore
@Test
public void isSerializable() {
scala.runtime.java8.JFunction0<String> f0 = () -> "foo";
scala.Function0<String> f0 = () -> "foo";
assertEquals("foo", SerializationUtils.clone(f0).apply());

scala.runtime.java8.JFunction1<String, String> f1 = (a) -> a.toUpperCase();
scala.Function1<String, String> f1 = (a) -> a.toUpperCase();
assertEquals("FOO", SerializationUtils.clone(f1).apply("foo"));

scala.runtime.java8.JFunction2<String, String, String> f2 = (a, b) -> a + b;
scala.Function2<String, String, String> f2 = (a, b) -> a + b;
assertEquals("foobar", SerializationUtils.clone(f2).apply("foo", "bar"));

scala.runtime.java8.JFunction3<String, String, String, String> f3 = (a, b, c) -> a + b + c;
scala.Function3<String, String, String, String> f3 = (a, b, c) -> a + b + c;
assertEquals("foobarbaz", SerializationUtils.clone(f3).apply("foo", "bar", "baz"));
}
*/

/*
// This version is for Scala 2.12.0-RC1 and is not compatible with 2.11. It's commented out to allow cross-building.
private static scala.concurrent.Future<Integer> futureExample(
scala.concurrent.Future<String> future, scala.concurrent.ExecutionContext ec) {
return future.map(func(s -> s.toUpperCase()), ec).map(func(s -> s.length()), ec);
return future.map(s -> s.toUpperCase(), ec).map(s -> s.length(), ec);
}
*/

private static void sideEffect() {
}
Expand Down
20 changes: 0 additions & 20 deletions src/test/java/scala/runtime/java8/SpecializedFactoryTest.java

This file was deleted.