Skip to content
Closed
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
8 changes: 4 additions & 4 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ lazy val parsing = project("parsing")
.settings(AutomaticModuleName.settings("pekko.http.parsing"))
.addPekkoModuleDependency("pekko-actor", "provided", PekkoCoreDependency.default)
.settings(Dependencies.parsing)
.settings(scalacOptions += "-language:_")
.settings(scalacOptions ++= (if (scalaVersion.value.startsWith("3")) Nil else Seq("-language:_")))
.settings(scalaMacroSupport)
.enablePlugins(ScaladocNoVerificationOfDiagrams)
.enablePlugins(ReproducibleBuildsPlugin)
Expand Down Expand Up @@ -136,7 +136,7 @@ lazy val http = project("http")
.addPekkoModuleDependency("pekko-stream", "provided", PekkoCoreDependency.default)
.settings(Dependencies.http)
.settings(
Compile / scalacOptions += "-language:_")
Compile / scalacOptions ++= (if (scalaVersion.value.startsWith("3")) Nil else Seq("-language:_")))
.settings(scalaMacroSupport)
.enablePlugins(BootstrapGenjavadoc, BoilerplatePlugin)
.enablePlugins(ReproducibleBuildsPlugin)
Expand Down Expand Up @@ -191,7 +191,7 @@ lazy val httpTestkit = project("http-testkit")
.settings(
// don't ignore Suites which is the default for the junit-interface
testOptions += Tests.Argument(TestFrameworks.JUnit, "--ignore-runners="),
Compile / scalacOptions ++= Seq("-language:_"),
Compile / scalacOptions ++= (if (scalaVersion.value.startsWith("3")) Nil else Seq("-language:_")),
Test / run / mainClass := Some("org.apache.pekko.http.javadsl.SimpleServerApp"))
.enablePlugins(BootstrapGenjavadoc, MultiNodeScalaTest, ScaladocNoVerificationOfDiagrams)
.enablePlugins(ReproducibleBuildsPlugin)
Expand Down Expand Up @@ -398,7 +398,7 @@ lazy val docs = project("docs")
name := "pekko-http-docs",
scalacOptions ++= Seq(
// Make sure we don't accidentally keep documenting deprecated calls
"-Xfatal-warnings",
"-Werror",
// Does not appear to lead to problems
"-Wconf:msg=The outer reference in this type test cannot be checked at run time:s"),
scalacOptions ++= (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,10 @@ private[http] object PoolInterface {
import hcps._
import setup.{ connectionContext, settings }
implicit val system = fm.system
val log: LoggingAdapter = Logging(system, poolId)(PoolLogSource)
val log: LoggingAdapter = {
implicit val ls: LogSource[PoolId] = PoolLogSource
Logging(system, poolId)
}

log.debug("Creating pool.")

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,10 @@ private[pekko] trait StageLoggingWithOverride extends GraphStageLogic {
case null =>
_log =
logOverride match {
case DefaultNoLogging =>
pekko.event.Logging(materializer.system, logSource)(LogSource.fromClass)
case DefaultNoLogging => {
implicit val classLogSource: LogSource[Class[?]] = LogSource.fromClass
pekko.event.Logging(materializer.system, logSource: Class[?])
}
case x => x
}
case _ =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,8 @@ sealed trait HttpMessage extends jm.HttpMessage {

/** Java API */
def getHeaders[T <: jm.HttpHeader](headerClass: Class[T]): JIterable[T] = {
headers[T](ClassTag[T](headerClass)).asJava
implicit val ct: ClassTag[T] = ClassTag(headerClass)
headers[T].asJava
}

/** Java API */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,9 +113,11 @@ abstract class TestRouteResult(_result: Future[RouteResult], awaitAtMost: Finite
/**
* Returns the first header of the response which is of the given class.
*/
def header[T >: Null <: HttpHeader](clazz: Class[T]): T =
response.header(ClassTag(clazz))
def header[T >: Null <: HttpHeader](clazz: Class[T]): T = {
implicit val ct: ClassTag[T] = ClassTag(clazz)
response.header[T]
.getOrElse(doFail(s"Expected header of type ${clazz.getSimpleName} but wasn't found."))
}

/**
* Expects the route to have been rejected, returning the list of rejections, or empty list if the route
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ trait RouteTest extends RequestBuilding with WSTestRequestBuilding with RouteTes
def charsetOption: Option[HttpCharset] = contentType.charsetOption
def charset: HttpCharset = charsetOption.getOrElse(sys.error("Binary entity does not have charset"))
def headers: immutable.Seq[HttpHeader] = rawResponse.headers
def header[T >: Null <: HttpHeader: ClassTag]: Option[T] = rawResponse.header[T](implicitly[ClassTag[T]])
def header[T >: Null <: HttpHeader: ClassTag]: Option[T] = rawResponse.header[T]
def header(name: String): Option[HttpHeader] = rawResponse.headers.find(_.is(name.toLowerCase))
def status: StatusCode = rawResponse.status

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -273,7 +273,8 @@ abstract class MultiNodeSpec(val myself: RoleName, _system: ActorSystem, _roles:
ActorSystem(MultiNodeSpec.getCallerName(classOf[MultiNodeSpec]), ConfigFactory.load(config.config)),
config.roles, config.deployments)

val log: LoggingAdapter = Logging(system, this.getClass)(LogSource.fromClass)
implicit val classLogSource: LogSource[Class[?]] = LogSource.fromClass
val log: LoggingAdapter = Logging(system, this.getClass: Class[?])

/**
* Enrich `.await()` onto all Awaitables, using remaining duration from the innermost
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,8 @@ abstract class DontLeakActorsOnFailingConnectionSpecs(poolImplementation: String
implicit val system: ActorSystem = ActorSystem("DontLeakActorsOnFailingConnectionSpecs-" + poolImplementation, config)
implicit val materializer: Materializer = Materializer.createMaterializer(system)

val log = Logging(system, getClass)(LogSource.fromClass)
implicit val classLogSource: LogSource[Class[?]] = LogSource.fromClass
val log = Logging(system, getClass: Class[?])

"Http.superPool" should {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -398,9 +398,12 @@ class EntityStreamingSpec extends RoutingSpec with ScalaFutures {

val jsonStreamingSupport: JsonEntityStreamingSupport = EntityStreamingSupport.json()

implicit val toResponseMarshaller: ToResponseMarshaller[Source[String, NotUsed]] =
PredefinedToResponseMarshallers.fromEntityStreamingSupportAndByteStringMarshaller[String, NotUsed](
scala.reflect.classTag[String], jsonStreamingSupport, csvStringMarshaller)
implicit val toResponseMarshaller: ToResponseMarshaller[Source[String, NotUsed]] = {
implicit val ct: scala.reflect.ClassTag[String] = scala.reflect.ClassTag(classOf[String])
implicit val ess: EntityStreamingSupport = jsonStreamingSupport
implicit val tbsm: ToByteStringMarshaller[String] = csvStringMarshaller
PredefinedToResponseMarshallers.fromEntityStreamingSupportAndByteStringMarshaller[String, NotUsed]
}

val route =
get {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,10 @@ class RejectionHandlerBuilder(asScala: server.RejectionHandler.Builder) {
*/
def handleAll[T <: Rejection](
t: Class[T], handler: function.Function[java.util.List[T], Route]): RejectionHandlerBuilder = {
asScala.handleAll { (rejections: collection.immutable.Seq[T]) => handler.apply(rejections.asJava).delegate }(
ClassTag(t))
implicit val ct: ClassTag[server.Rejection] = ClassTag(t)
asScala.handleAll { (rejections: collection.immutable.Seq[server.Rejection]) =>
handler.apply(rejections.asInstanceOf[Seq[T]].asJava).delegate
}
this
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,10 @@ abstract class Directive[L](implicit val ev: Tuple[L]) {
/**
* Joins two directives into one which runs the second directive if the first one rejects.
*/
def or[R >: L](that: Directive[R]): Directive[R] =
recover(rejections => directives.BasicDirectives.mapRejections(rejections ++ _) & that)(that.ev)
def or[R >: L](that: Directive[R]): Directive[R] = {
implicit val ev: Tuple[R] = that.ev
recover(rejections => directives.BasicDirectives.mapRejections(rejections ++ _) & that)
}

/**
* Joins two directives into one which extracts the concatenation of its base directive extractions.
Expand All @@ -70,7 +72,8 @@ abstract class Directive[L](implicit val ev: Tuple[L]) {
* instance of type `A` (which is usually a case class).
*/
def as[A](constructor: ConstructFromTuple[L, A]): Directive1[A] = {
def validatedMap[R](f: L => R)(implicit tupler: Tupler[R]): Directive[tupler.Out] =
def validatedMap[R](f: L => R)(implicit tupler: Tupler[R]): Directive[tupler.Out] = {
implicit val tupleEv: Tuple[tupler.Out] = tupler.OutIsTuple
Directive[tupler.Out] { inner =>
tapply { values => ctx =>
def futureRouteResult(): Future[RouteResult] = {
Expand All @@ -84,7 +87,8 @@ abstract class Directive[L](implicit val ev: Tuple[L]) {
}
futureRouteResult()
}
}(tupler.OutIsTuple)
}
}

validatedMap(constructor)
}
Expand All @@ -93,8 +97,10 @@ abstract class Directive[L](implicit val ev: Tuple[L]) {
* Maps over this directive using the given function, which can produce either a tuple or any other value
* (which will then we wrapped into a [[scala.Tuple1]]).
*/
def tmap[R](f: L => R)(implicit tupler: Tupler[R]): Directive[tupler.Out] =
Directive[tupler.Out] { inner => tapply { values => inner(tupler(f(values))) } }(tupler.OutIsTuple)
def tmap[R](f: L => R)(implicit tupler: Tupler[R]): Directive[tupler.Out] = {
implicit val tupleEv: Tuple[tupler.Out] = tupler.OutIsTuple
Directive[tupler.Out] { inner => tapply { values => inner(tupler(f(values))) } }
}

/**
* Flatmaps this directive using the given function.
Expand Down Expand Up @@ -124,12 +130,14 @@ abstract class Directive[L](implicit val ev: Tuple[L]) {
* If it is not defined however, the returned directive will reject with the given rejections.
*/
def tcollect[R](pf: PartialFunction[L, R], rejections: Rejection*)(
implicit tupler: Tupler[R]): Directive[tupler.Out] =
implicit tupler: Tupler[R]): Directive[tupler.Out] = {
implicit val tupleEv: Tuple[tupler.Out] = tupler.OutIsTuple
Directive[tupler.Out] { inner =>
tapply { values => ctx =>
{ if (pf.isDefinedAt(values)) inner(tupler(pf(values)))(ctx) else ctx.reject(rejections: _*) }
}
}(tupler.OutIsTuple)
}
}

/**
* Creates a new directive that is able to recover from rejections that were produced by `this` Directive
Expand Down Expand Up @@ -188,10 +196,12 @@ object Directive {
* Adds helper functions to `Directive0`
*/
implicit class Directive0Support(val underlying: Directive0) extends AnyVal {
def wrap[R](f: => Directive[R]): Directive[R] =
def wrap[R](f: => Directive[R]): Directive[R] = {
implicit val tupleEv: Tuple[R] = Tuple.yes[R]
underlying.tflatMap { _ =>
f
}(Tuple.yes[R]) // we will create a Directive[R], so we know it will be tupled correctly
} // we will create a Directive[R], so we know it will be tupled correctly
}
}

/**
Expand Down Expand Up @@ -251,10 +261,12 @@ object ConjunctionMagnet {
implicit join: TupleOps.Join[L, R]): ConjunctionMagnet[L] { type Out = Directive[join.Out] } =
new ConjunctionMagnet[L] {
type Out = Directive[join.Out]
def apply(underlying: Directive[L]) =
def apply(underlying: Directive[L]) = {
implicit val joinOutIsTuple: Tuple[join.Out] = Tuple.yes[join.Out]
Directive[join.Out] { inner =>
underlying.tapply { prefix => other.tapply { suffix => inner(join(prefix, suffix)) } }
}(Tuple.yes) // we know that join will only ever produce tuples
}
}
}

implicit def fromStandardRoute[L](route: StandardRoute): ConjunctionMagnet[L] { type Out = StandardRoute } =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -156,20 +156,20 @@ object PathMatcher extends ImplicitPathMatcherConstruction {
/**
* Creates a PathMatcher that always matches, consumes nothing and extracts the given Tuple of values.
*/
def provide[L: Tuple](extractions: L): PathMatcher[L] =
def provide[L](extractions: L)(implicit ev: Tuple[L]): PathMatcher[L] =
new PathMatcher[L] {
def apply(path: Path) = Matched(path, extractions)(ev)
def apply(path: Path) = Matched(path, extractions)
}

/**
* Creates a PathMatcher that matches and consumes the given path prefix and extracts the given list of extractions.
* If the given prefix is empty the returned PathMatcher matches always and consumes nothing.
*/
def apply[L: Tuple](prefix: Path, extractions: L): PathMatcher[L] =
def apply[L](prefix: Path, extractions: L)(implicit ev: Tuple[L]): PathMatcher[L] =
if (prefix.isEmpty) provide(extractions)
else new PathMatcher[L] {
def apply(path: Path) =
if (path.startsWith(prefix)) Matched(path.dropChars(prefix.charCount), extractions)(ev)
if (path.startsWith(prefix)) Matched(path.dropChars(prefix.charCount), extractions)
else Unmatched
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import scala.util.{ Failure, Success, Try }
import org.apache.pekko
import pekko.http.scaladsl.marshalling.ToResponseMarshaller
import pekko.http.scaladsl.server.Directives._
import pekko.http.scaladsl.server.util.Tuple
import pekko.http.scaladsl.server.util.Tupler
import pekko.http.scaladsl.util.FastFuture._
import pekko.pattern.{ CircuitBreaker, CircuitBreakerOpenException }
Expand Down Expand Up @@ -102,10 +103,11 @@ object OnSuccessMagnet {
implicit def apply[T](future: => Future[T])(implicit tupler: Tupler[T]): OnSuccessMagnet { type Out = tupler.Out } =
new OnSuccessMagnet {
type Out = tupler.Out
implicit val tupleEv: Tuple[tupler.Out] = tupler.OutIsTuple
val directive = Directive[tupler.Out] { inner => ctx =>
import ctx.executionContext
future.fast.flatMap(t => inner(tupler(t))(ctx))
}(tupler.OutIsTuple)
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ trait PathDirectives extends PathMatchers with ImplicitPathMatcherConstruction w
def rawPathPrefix[L](pm: PathMatcher[L]): Directive[L] = {
implicit val LIsTuple = pm.ev
extract(ctx => pm(ctx.unmatchedPath)).flatMap {
case Matched(rest, values) => tprovide(values)(LIsTuple) & mapRequestContext(_.withUnmatchedPath(rest))
case Matched(rest, values) => tprovide[L](values) & mapRequestContext(_.withUnmatchedPath(rest))
case Unmatched => reject
}
}
Expand Down Expand Up @@ -100,7 +100,7 @@ trait PathDirectives extends PathMatchers with ImplicitPathMatcherConstruction w
def pathSuffix[L](pm: PathMatcher[L]): Directive[L] = {
implicit val LIsTuple = pm.ev
extract(ctx => pm(ctx.unmatchedPath.reverse)).flatMap {
case Matched(rest, values) => tprovide(values)(LIsTuple) & mapRequestContext(_.withUnmatchedPath(rest.reverse))
case Matched(rest, values) => tprovide[L](values) & mapRequestContext(_.withUnmatchedPath(rest.reverse))
case Unmatched => reject
}
}
Expand Down
16 changes: 14 additions & 2 deletions project/Common.scala
Original file line number Diff line number Diff line change
Expand Up @@ -24,19 +24,31 @@ object Common extends AutoPlugin {
"-deprecation",
"-encoding", "UTF-8", // yes, this is 2 args
"-unchecked",
"-Ywarn-dead-code",
"-Wconf:msg=reached max recursion depth:s",
"-Wconf:msg=Prefer the Scala annotation over Java's `@Deprecated`:s",
"-release:" + javacTarget),
scalacOptions ++= onlyOnScala2(Seq(
"-Ywarn-dead-code",
"-Xlint",
// Exhaustivity checking is only useful for simple sealed hierarchies and matches without filters.
// In all other cases, the warning is non-actionable: you get spurious warnings that need to be suppressed
// verbosely. So, opt out of those in general.
"-Wconf:cat=other-match-analysis&msg=match may not be exhaustive:s")).value,
scalacOptions ++= onlyOnScala3(Seq(
"-Wconf:cat=deprecation:s",
"-Yfuture-lazy-vals")).value,
"-Yfuture-lazy-vals",
"-Wconf:msg=Implicit parameters should be provided with a `using` clause:s",
"-Wconf:msg=is deprecated for wildcard arguments of types:s",
"-Wconf:msg=The trailing ` _` for eta-expansion is unnecessary:s",
"-Wconf:msg=with as a type operator has been deprecated:s",
"-Wconf:msg=Unreachable case except for null:s",
"-Wconf:msg=is no longer supported for vararg splices:s",
"-Wconf:msg=is not declared infix:s",
"-Wconf:msg=auto insertion will be deprecated:s",
"-Wconf:msg=Ignoring \\[this\\] qualifier:s",
"-Wconf:msg=trait App in package scala is deprecated:s",
"-Wconf:msg=pattern binding uses refutable extractor:s",
"-Wconf:msg=bad option.*-Yfuture-lazy-vals:s")).value,
javacOptions ++=
Seq("-encoding", "UTF-8", "--release", javacTarget),
mimaReportSignatureProblems := true,
Expand Down