Remove Scala 3 inline keyword from Java specific conversion methods

This commit is contained in:
Matthew de Detrich 2023-12-31 11:18:57 +11:00 committed by Matthew de Detrich
parent 7ed85713e2
commit f8c4aee8be
9 changed files with 76 additions and 28 deletions

View file

@ -37,7 +37,7 @@ import pekko.actor.typed.internal.ActorRefImpl
import pekko.actor.typed.internal.InternalRecipientRef
import pekko.actor.typed.receptionist.Receptionist
import pekko.annotation.InternalApi
import pekko.util.FutureConverters
import pekko.util.FutureConverters._
/**
* INTERNAL API
@ -108,7 +108,7 @@ import pekko.util.FutureConverters
private val terminationPromise = Promise[Done]()
override def terminate(): Unit = terminationPromise.trySuccess(Done)
override def whenTerminated: Future[Done] = terminationPromise.future
override def getWhenTerminated: CompletionStage[Done] = FutureConverters.asJava(whenTerminated)
override def getWhenTerminated: CompletionStage[Done] = whenTerminated.asJava
override val startTime: Long = System.currentTimeMillis()
override def uptime: Long = System.currentTimeMillis() - startTime
override def threadFactory: java.util.concurrent.ThreadFactory = new ThreadFactory {

View file

@ -0,0 +1,47 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.pekko.util;
import java.time.Duration;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import scala.Option;
import scala.concurrent.Future;
/**
* These tests are here to ensure that methods from {@link org.apache.pekko.util.FutureConverters},
* {@link org.apache.pekko.util.JavaDurationConverters} and {@link
* org.apache.pekko.util.OptionConverters} for use within Java can be compiled from with Java
* sources. This is because methods marked with the Scala 3 inline keyword cannot be called from
* within Java (see https://github.com/lampepfl/dotty/issues/19346)
*/
public class JavaConverterScala3InlineTest {
public void compileTest() {
OptionConverters.toScala(Optional.empty());
OptionConverters.toScala(OptionalDouble.of(0));
OptionConverters.toScala(OptionalInt.of(0));
OptionConverters.toScala(OptionalLong.of(0));
OptionConverters.toJava(Option.empty());
FutureConverters.asJava(Future.successful(""));
FutureConverters.asScala(CompletableFuture.completedFuture(""));
JavaDurationConverters.asFiniteDuration(Duration.ofMillis(0));
}
}

View file

@ -42,7 +42,7 @@ import pekko.actor.typed.internal.PropsImpl.DispatcherSameAsParent
import pekko.actor.typed.internal.SystemMessage
import pekko.actor.typed.scaladsl.Behaviors
import pekko.annotation.InternalApi
import pekko.util.FutureConverters
import pekko.util.FutureConverters._
/**
* INTERNAL API. Lightweight wrapper for presenting a classic ActorSystem to a Behavior (via the context).
@ -120,7 +120,7 @@ import pekko.util.FutureConverters
override lazy val whenTerminated: scala.concurrent.Future[pekko.Done] =
system.whenTerminated.map(_ => Done)(parasitic)
override lazy val getWhenTerminated: CompletionStage[pekko.Done] =
FutureConverters.asJava(whenTerminated)
whenTerminated.asJava
override def systemActorOf[U](behavior: Behavior[U], name: String, props: Props): ActorRef[U] = {
val ref = system.systemActorOf(

View file

@ -34,12 +34,12 @@ private[pekko] object FutureConverters {
@inline final def asJava[T](f: Future[T]): CompletionStage[T] = javaapi.FutureConverters.asJava(f)
implicit final class FutureOps[T](private val f: Future[T]) extends AnyVal {
@inline def asJava: CompletionStage[T] = FutureConverters.asJava(f)
@inline def asJava: CompletionStage[T] = javaapi.FutureConverters.asJava(f)
}
@inline final def asScala[T](cs: CompletionStage[T]): Future[T] = javaapi.FutureConverters.asScala(cs)
implicit final class CompletionStageOps[T](private val cs: CompletionStage[T]) extends AnyVal {
@inline def asScala: Future[T] = FutureConverters.asScala(cs)
@inline def asScala: Future[T] = javaapi.FutureConverters.asScala(cs)
}
}

View file

@ -28,8 +28,6 @@ private[pekko] object FutureConverters {
def asJava[T](f: Future[T]): CompletionStage[T] = javaapi.FutureConverters.asJava(f)
implicit final class FutureOps[T](private val f: Future[T]) extends AnyVal {
// Change to FutureConverters.asJava(f) once https://github.com/lampepfl/dotty/issues/19346
// is resolved and the asJava method is marked as inline
inline def asJava: CompletionStage[T] = javaapi.FutureConverters.asJava(f)
}
@ -38,8 +36,6 @@ private[pekko] object FutureConverters {
def asScala[T](cs: CompletionStage[T]): Future[T] = javaapi.FutureConverters.asScala(cs)
implicit final class CompletionStageOps[T](private val cs: CompletionStage[T]) extends AnyVal {
// Change to FutureConverters.asScala(cs) once https://github.com/lampepfl/dotty/issues/19346
// is resolved and the asScala method is marked as inline
inline def asScala: Future[T] = javaapi.FutureConverters.asScala(cs)
}
}

View file

@ -22,15 +22,17 @@ import scala.jdk.OptionShape
@InternalStableApi
private[pekko] object OptionConverters {
inline final def toScala[A](o: Optional[A]): Option[A] = scala.jdk.javaapi.OptionConverters.toScala(o)
// Ideally these methods should have the Scala 3 inline keyword but then Java sources are
// unable to call these methods, see https://github.com/lampepfl/dotty/issues/19346
final def toScala[A](o: Optional[A]): Option[A] = scala.jdk.javaapi.OptionConverters.toScala(o)
inline def toScala(o: OptionalDouble): Option[java.lang.Double] = scala.jdk.javaapi.OptionConverters.toScala(o)
def toScala(o: OptionalDouble): Option[java.lang.Double] = scala.jdk.javaapi.OptionConverters.toScala(o)
inline def toScala(o: OptionalInt): Option[java.lang.Integer] = scala.jdk.javaapi.OptionConverters.toScala(o)
def toScala(o: OptionalInt): Option[java.lang.Integer] = scala.jdk.javaapi.OptionConverters.toScala(o)
inline def toScala(o: OptionalLong): Option[java.lang.Long] = scala.jdk.javaapi.OptionConverters.toScala(o)
def toScala(o: OptionalLong): Option[java.lang.Long] = scala.jdk.javaapi.OptionConverters.toScala(o)
inline final def toJava[A](o: Option[A]): Optional[A] = scala.jdk.javaapi.OptionConverters.toJava(o)
final def toJava[A](o: Option[A]): Optional[A] = scala.jdk.javaapi.OptionConverters.toJava(o)
implicit final class RichOptional[A](private val o: java.util.Optional[A]) extends AnyVal {
inline def toScala: Option[A] = scala.jdk.OptionConverters.RichOptional(o).toScala

View file

@ -108,8 +108,10 @@ abstract class ActorSelection extends Serializable {
* supplied `timeout`.
*/
@deprecated("Use the overloaded method resolveOne which accepts java.time.Duration instead.", since = "Akka 2.5.20")
def resolveOneCS(timeout: FiniteDuration): CompletionStage[ActorRef] =
FutureConverters.asJava[ActorRef](resolveOne(timeout))
def resolveOneCS(timeout: FiniteDuration): CompletionStage[ActorRef] = {
import FutureConverters._
resolveOne(timeout).asJava
}
/**
* Java API for [[#resolveOne]]
@ -133,8 +135,9 @@ abstract class ActorSelection extends Serializable {
* supplied `timeout`.
*/
def resolveOne(timeout: java.time.Duration): CompletionStage[ActorRef] = {
import FutureConverters._
import JavaDurationConverters._
FutureConverters.asJava[ActorRef](resolveOne(timeout.asScala))
resolveOne(timeout.asScala).asJava
}
override def toString: String = {

View file

@ -30,7 +30,7 @@ import pekko.PekkoException
import pekko.actor.{ ExtendedActorSystem, Scheduler }
import pekko.dispatch.ExecutionContexts.parasitic
import pekko.pattern.internal.{ CircuitBreakerNoopTelemetry, CircuitBreakerTelemetry }
import pekko.util.FutureConverters
import pekko.util.FutureConverters._
import pekko.util.JavaDurationConverters._
import pekko.util.Unsafe
@ -399,9 +399,9 @@ class CircuitBreaker(
* `scala.concurrent.TimeoutException` if the call timed out
*/
def callWithCircuitBreakerCS[T](body: Callable[CompletionStage[T]]): CompletionStage[T] =
FutureConverters.asJava[T](callWithCircuitBreaker(new Callable[Future[T]] {
override def call(): Future[T] = FutureConverters.asScala(body.call())
}))
callWithCircuitBreaker(new Callable[Future[T]] {
override def call(): Future[T] = body.call().asScala
}).asJava
/**
* Java API (8) for [[#withCircuitBreaker]].
@ -414,9 +414,9 @@ class CircuitBreaker(
def callWithCircuitBreakerCS[T](
body: Callable[CompletionStage[T]],
defineFailureFn: BiFunction[Optional[T], Optional[Throwable], java.lang.Boolean]): CompletionStage[T] =
FutureConverters.asJava[T](callWithCircuitBreaker(new Callable[Future[T]] {
override def call(): Future[T] = FutureConverters.asScala(body.call())
}, defineFailureFn))
callWithCircuitBreaker(new Callable[Future[T]] {
override def call(): Future[T] = body.call().asScala
}, defineFailureFn).asJava
/**
* Wraps invocations of synchronous calls that need to be protected.

View file

@ -13,7 +13,7 @@
package org.apache.pekko.stream
import org.apache.pekko.util.FutureConverters
import org.apache.pekko.util.FutureConverters._
import java.util.concurrent.CompletionStage
@ -67,10 +67,10 @@ import scala.concurrent.Future
package object scaladsl {
implicit class SourceToCompletionStage[Out, T](val src: Source[Out, Future[T]]) extends AnyVal {
def toCompletionStage(): Source[Out, CompletionStage[T]] =
src.mapMaterializedValue(f => FutureConverters.asJava(f))
src.mapMaterializedValue(_.asJava)
}
implicit class SinkToCompletionStage[In, T](val sink: Sink[In, Future[T]]) extends AnyVal {
def toCompletionStage(): Sink[In, CompletionStage[T]] =
sink.mapMaterializedValue(f => FutureConverters.asJava(f))
sink.mapMaterializedValue(_.asJava)
}
}