diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index 55c94aa06..6d67bf18e 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -21,7 +21,7 @@ jobs: strategy: fail-fast: false matrix: - SCALA_VERSION: [2.12, 2.13, 3] + SCALA_VERSION: [2.13, 3] JDK: [17, 21] PEKKO_VERSION: ['default'] steps: diff --git a/.github/workflows/validate-and-test.yml b/.github/workflows/validate-and-test.yml index 05b1fe2bf..9ffb326f0 100644 --- a/.github/workflows/validate-and-test.yml +++ b/.github/workflows/validate-and-test.yml @@ -70,7 +70,7 @@ jobs: strategy: fail-fast: false matrix: - SCALA_VERSION: [2.12, 2.13, 3.3] + SCALA_VERSION: [2.13, 3.3] JDK: [17] steps: - name: Checkout diff --git a/LICENSE b/LICENSE index 5782dafd8..bbc10fd00 100644 --- a/LICENSE +++ b/LICENSE @@ -212,8 +212,8 @@ Copyright 2014 Twitter, Inc. pekko-http-core contains code from scala-collection-compat in the `org.apache.pekko.http.ccompat` package distributed under the Apache 2.0 license. -- http-core/src/main/scala-2.13-/org/apache/pekko/http/ccompat/package.scala -- http-core/src/main/scala-2.13-/org/apache/pekko/http/ccompat/CompatImpl.scala +- http-core/src/main/scala-2.13/org/apache/pekko/http/ccompat/package.scala +- http-core/src/main/scala-2.13/org/apache/pekko/http/ccompat/CompatImpl.scala Copyright EPFL and Lightbend, Inc. diff --git a/build.sbt b/build.sbt index 55e8e4c16..0f75cb85e 100644 --- a/build.sbt +++ b/build.sbt @@ -88,40 +88,17 @@ lazy val root = Project( Compile / headerCreate / unmanagedSources := (baseDirectory.value / "project").**("*.scala").get) .aggregate(aggregatedProjects: _*) -/** - * Adds a `src/.../scala-2.13+` source directory for Scala 2.13 and newer - * and a `src/.../scala-2.13-` source directory for Scala version older than 2.13 - */ -def add213CrossDirs(config: Configuration): Seq[Setting[_]] = Seq( - config / unmanagedSourceDirectories += { - val sourceDir = (config / sourceDirectory).value - CrossVersion.partialVersion(scalaVersion.value) match { - case Some((e, n)) if e > 2 || (e == 2 && n >= 13) => sourceDir / "scala-2.13+" - case _ => sourceDir / "scala-2.13-" - } - }) - -val commonSettings = - add213CrossDirs(Compile) ++ - add213CrossDirs(Test) - val scalaMacroSupport = Seq( scalacOptions ++= { CrossVersion.partialVersion(scalaVersion.value) match { - case Some((2, n)) if n >= 13 => + case Some((2, n)) => Seq("-Ymacro-annotations") case _ => Seq.empty } - }, - libraryDependencies ++= (CrossVersion.partialVersion(scalaVersion.value) match { - case Some((2, n)) if n < 13 => - Seq(compilerPlugin(("org.scalamacros" % "paradise" % "2.1.1").cross(CrossVersion.full))) - case _ => Seq.empty - })) + }) lazy val parsing = project("parsing") - .settings(commonSettings) .settings(AutomaticModuleName.settings("pekko.http.parsing")) .addPekkoModuleDependency("pekko-actor", "provided", PekkoCoreDependency.default) .settings(Dependencies.parsing) @@ -132,7 +109,6 @@ lazy val parsing = project("parsing") .disablePlugins(MimaPlugin) lazy val httpCore = project("http-core") - .settings(commonSettings) .settings(AutomaticModuleName.settings("pekko.http.core")) .settings(AddMetaInfLicenseFiles.httpCoreSettings) .dependsOn(parsing /*, httpScalafixRules % ScalafixConfig*/ ) @@ -146,13 +122,9 @@ lazy val httpCore = project("http-core") .settings(scalaMacroSupport) .enablePlugins(BootstrapGenjavadoc) .enablePlugins(ReproducibleBuildsPlugin) - .enablePlugins(Pre213Preprocessor).settings( - Pre213Preprocessor.pre213Files := Seq( - "headers.scala", "HttpMessage.scala", "LanguageRange.scala", "CacheDirective.scala", "LinkValue.scala")) .disablePlugins(ScalafixPlugin) lazy val http = project("http") - .settings(commonSettings) .settings(AutomaticModuleName.settings("pekko.http")) .dependsOn(httpCore) .addPekkoModuleDependency("pekko-stream", "provided", PekkoCoreDependency.default) @@ -160,14 +132,10 @@ lazy val http = project("http") .settings( Compile / scalacOptions += "-language:_") .settings(scalaMacroSupport) - .enablePlugins(Pre213Preprocessor).settings( - Pre213Preprocessor.pre213Files := Seq( - "scaladsl/server/directives/FormFieldDirectives.scala", "scaladsl/server/directives/RespondWithDirectives.scala")) .enablePlugins(BootstrapGenjavadoc, BoilerplatePlugin) .enablePlugins(ReproducibleBuildsPlugin) lazy val http2Tests = project("http2-tests") - .settings(commonSettings) .settings(AutomaticModuleName.settings("pekko.http.http2")) .dependsOn(httpCore, httpTestkit % "test", httpCore % "test->test") .addPekkoModuleDependency("pekko-stream", "provided", PekkoCoreDependency.default) @@ -209,7 +177,6 @@ lazy val http2Tests = project("http2-tests") .disablePlugins(MimaPlugin) // experimental module still lazy val httpTestkit = project("http-testkit") - .settings(commonSettings) .settings(AutomaticModuleName.settings("pekko.http.testkit")) .dependsOn(http) .addPekkoModuleDependency("pekko-stream-testkit", "provided", PekkoCoreDependency.default) @@ -225,7 +192,6 @@ lazy val httpTestkit = project("http-testkit") .disablePlugins(MimaPlugin) // testkit, no bin compat guaranteed lazy val httpTestkitMunit = project("http-testkit-munit") - .settings(commonSettings) .settings(AutomaticModuleName.settings("pekko.http.testkit.munit")) .dependsOn(http, httpTestkit) .addPekkoModuleDependency("pekko-stream-testkit", "provided", PekkoCoreDependency.default) @@ -234,7 +200,6 @@ lazy val httpTestkitMunit = project("http-testkit-munit") .disablePlugins(MimaPlugin) // testkit, no bin compat guaranteed lazy val httpTests = project("http-tests") - .settings(commonSettings) .settings(Dependencies.httpTests) .dependsOn(httpSprayJson, httpXml, httpJackson, httpTestkit % "test", httpCore % "test->test", @@ -261,7 +226,6 @@ lazy val httpTests = project("http-tests") }) lazy val httpJmhBench = project("http-bench-jmh") - .settings(commonSettings) .dependsOn(http, httpCors, http2Tests % "compile->compile,test") .addPekkoModuleDependency("pekko-stream", "", PekkoCoreDependency.default) .enablePlugins(JmhPlugin) @@ -269,7 +233,6 @@ lazy val httpJmhBench = project("http-bench-jmh") .disablePlugins(MimaPlugin) lazy val httpMarshallersScala = project("http-marshallers-scala") - .settings(commonSettings) .enablePlugins(NoPublish /*, AggregatePRValidation*/ ) .disablePlugins(MimaPlugin) .aggregate(httpSprayJson, httpXml) @@ -287,7 +250,6 @@ lazy val httpSprayJson = .settings(Dependencies.httpSprayJson) lazy val httpMarshallersJava = project("http-marshallers-java") - .settings(commonSettings) .enablePlugins(NoPublish /*, AggregatePRValidation*/ ) .disablePlugins(MimaPlugin) .aggregate(httpJackson) @@ -304,7 +266,6 @@ lazy val httpJackson = lazy val httpCaching = project("http-caching") .settings( name := "pekko-http-caching") - .settings(commonSettings) .settings(AutomaticModuleName.settings("pekko.http.caching")) .addPekkoModuleDependency("pekko-stream", "provided", PekkoCoreDependency.default) .addPekkoModuleDependency("pekko-stream-testkit", "provided", PekkoCoreDependency.default) @@ -315,7 +276,6 @@ lazy val httpCaching = project("http-caching") lazy val httpCors = project("http-cors") .settings( name := "pekko-http-cors") - .settings(commonSettings) .settings(AutomaticModuleName.settings("pekko.http.cors")) .settings(AddMetaInfLicenseFiles.httpCorsSettings) .addPekkoModuleDependency("pekko-stream", "provided", PekkoCoreDependency.default) @@ -335,7 +295,6 @@ def httpMarshallersScalaSubproject(moduleName: String) = .dependsOn(http) .settings( name := s"pekko-http-$moduleName") - .settings(commonSettings) .enablePlugins(BootstrapGenjavadoc) .enablePlugins(ReproducibleBuildsPlugin) @@ -346,7 +305,6 @@ def httpMarshallersJavaSubproject(moduleName: String) = .settings( name := s"pekko-http-$moduleName") .dependsOn(http) - .settings(commonSettings) .enablePlugins(BootstrapGenjavadoc) .enablePlugins(ReproducibleBuildsPlugin) diff --git a/http-core/src/main/scala-2.13-/org/apache/pekko/http/ccompat/CompatImpl.scala b/http-core/src/main/scala-2.13-/org/apache/pekko/http/ccompat/CompatImpl.scala deleted file mode 100644 index 0e27de2c9..000000000 --- a/http-core/src/main/scala-2.13-/org/apache/pekko/http/ccompat/CompatImpl.scala +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * license agreements; and to You under the Apache License, version 2.0: - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * This file is part of the Apache Pekko project, which was derived from Akka. - */ - -/* - * Copyright (C) 2019-2022 Lightbend Inc. - */ - -/* - * Scala (https://www.scala-lang.org) - * - * Copyright EPFL and Lightbend, Inc. - * - * Licensed under Apache License 2.0 - * (http://www.apache.org/licenses/LICENSE-2.0). - * - * See the NOTICE file distributed with this work for - * additional information regarding copyright ownership. - */ - -package org.apache.pekko.http.ccompat - -import scala.collection.generic.CanBuildFrom -import scala.collection.mutable - -/** - * INTERNAL API - * - * Based on https://github.com/scala/scala-collection-compat/blob/main/compat/src/main/scala-2.11_2.12/scala/collection/compat/CompatImpl.scala - * but reproduced here so we don't need to add a dependency on this library. It contains much more than we need right now, and is - * not promising binary compatibility yet at the time of writing. - */ -private[ccompat] object CompatImpl { - def simpleCBF[A, C](f: => mutable.Builder[A, C]): CanBuildFrom[Any, A, C] = new CanBuildFrom[Any, A, C] { - def apply(from: Any): mutable.Builder[A, C] = apply() - def apply(): mutable.Builder[A, C] = f - } -} diff --git a/http-core/src/main/scala-2.13-/org/apache/pekko/http/ccompat/MapHelpers.scala b/http-core/src/main/scala-2.13-/org/apache/pekko/http/ccompat/MapHelpers.scala deleted file mode 100644 index b69a0fbfa..000000000 --- a/http-core/src/main/scala-2.13-/org/apache/pekko/http/ccompat/MapHelpers.scala +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * license agreements; and to You under the Apache License, version 2.0: - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * This file is part of the Apache Pekko project, which was derived from Akka. - */ - -/* - * Copyright (C) 2018-2022 Lightbend Inc. - */ - -package org.apache.pekko.http.ccompat - -/** - * INTERNAL API - */ -object MapHelpers { - def convertMapToScala[K, V](jmap: java.util.Map[K, V]): scala.collection.immutable.Map[K, V] = { - import scala.collection.JavaConverters._ - Map.empty ++ jmap.asScala - } -} diff --git a/http-core/src/main/scala-2.13-/org/apache/pekko/http/ccompat/imm/package.scala b/http-core/src/main/scala-2.13-/org/apache/pekko/http/ccompat/imm/package.scala deleted file mode 100644 index 3775d09df..000000000 --- a/http-core/src/main/scala-2.13-/org/apache/pekko/http/ccompat/imm/package.scala +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * license agreements; and to You under the Apache License, version 2.0: - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * This file is part of the Apache Pekko project, which was derived from Akka. - */ - -/* - * Copyright (C) 2018-2022 Lightbend Inc. - */ - -package org.apache.pekko.http.ccompat - -import scala.collection.immutable - -/** - * INTERNAL API - */ -package object imm { - implicit class SortedSetOps[A](val real: immutable.SortedSet[A]) extends AnyVal { - def unsorted: immutable.Set[A] = real - } - - implicit class StreamOps[A](val underlying: immutable.Stream[A]) extends AnyVal { - // renamed in 2.13 - def lazyAppendedAll[B >: A](rest: => TraversableOnce[B]): Stream[B] = underlying.append(rest) - } -} diff --git a/http-core/src/main/scala-2.13-/org/apache/pekko/http/ccompat/package.scala b/http-core/src/main/scala-2.13-/org/apache/pekko/http/ccompat/package.scala deleted file mode 100644 index 478ca1f19..000000000 --- a/http-core/src/main/scala-2.13-/org/apache/pekko/http/ccompat/package.scala +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * license agreements; and to You under the Apache License, version 2.0: - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * This file is part of the Apache Pekko project, which was derived from Akka. - */ - -/* - * Copyright (C) 2018-2022 Lightbend Inc. - */ - -/* - * Scala (https://www.scala-lang.org) - * - * Copyright EPFL and Lightbend, Inc. - * - * Licensed under Apache License 2.0 - * (http://www.apache.org/licenses/LICENSE-2.0). - * - * See the NOTICE file distributed with this work for - * additional information regarding copyright ownership. - */ - -package org.apache.pekko.http - -import org.apache.pekko -import scala.collection.generic.{ CanBuildFrom, GenericCompanion } -import scala.collection.{ mutable, GenTraversable } -import scala.{ collection => c } - -/** - * INTERNAL API - * - * Partly based on https://github.com/scala/scala-collection-compat/blob/main/compat/src/main/scala-2.11_2.12/scala/collection/compat/PackageShared.scala - * but reproduced here so we don't need to add a dependency on this library. It contains much more than we need right now, and is - * not promising binary compatibility yet at the time of writing. - */ -package object ccompat { - import CompatImpl._ - - implicit def genericCompanionToCBF[A, CC[X] <: GenTraversable[X]]( - fact: GenericCompanion[CC]): CanBuildFrom[Any, A, CC[A]] = - simpleCBF(fact.newBuilder[A]) - - // This really belongs into scala.collection but there's already a package object - // in scala-library so we can't add to it - type IterableOnce[+X] = c.TraversableOnce[X] - val IterableOnce = c.TraversableOnce - - implicit class RichQueue[T](val queue: mutable.Queue[T]) extends AnyVal { - // missing in 2.12 - def -=(element: T): Unit = queue.dequeueAll(_ == element) - } -} - -/** - * INTERNAL API - */ -package ccompat { - trait Builder[-Elem, +To] extends mutable.Builder[Elem, To] { self => - // This became final in 2.13 so cannot be overridden there anymore - final override def +=(elem: Elem): this.type = addOne(elem) - def addOne(elem: Elem): this.type = self.+=(elem) - } - - trait QuerySeqOptimized extends scala.collection.immutable.LinearSeq[(String, String)] - with scala.collection.LinearSeqOptimized[(String, String), pekko.http.scaladsl.model.Uri.Query] { - self: pekko.http.scaladsl.model.Uri.Query => - override def newBuilder: mutable.Builder[(String, String), pekko.http.scaladsl.model.Uri.Query] = - pekko.http.scaladsl.model.Uri.Query.newBuilder - } -} diff --git a/http-core/src/main/scala-2.13-/org/apache/pekko/http/scaladsl/util/FastFuture.scala b/http-core/src/main/scala-2.13-/org/apache/pekko/http/scaladsl/util/FastFuture.scala deleted file mode 100644 index e773fb683..000000000 --- a/http-core/src/main/scala-2.13-/org/apache/pekko/http/scaladsl/util/FastFuture.scala +++ /dev/null @@ -1,139 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * license agreements; and to You under the Apache License, version 2.0: - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * This file is part of the Apache Pekko project, which was derived from Akka. - */ - -/* - * Copyright (C) 2009-2022 Lightbend Inc. - */ - -package org.apache.pekko.http.scaladsl.util - -import scala.language.higherKinds -import scala.util.control.NonFatal -import scala.util.{ Failure, Success, Try } -import scala.collection.generic.CanBuildFrom -import scala.concurrent.duration.Duration -import scala.concurrent._ - -/** - * Provides alternative implementations of the basic transformation operations defined on [[scala.concurrent.Future]], - * which try to avoid scheduling to an [[scala.concurrent.ExecutionContext]] if possible, i.e. if the given future - * value is already present. - */ -class FastFuture[A](val future: Future[A]) extends AnyVal { - import FastFuture._ - - def map[B](f: A => B)(implicit ec: ExecutionContext): Future[B] = - transformWith(a => FastFuture.successful(f(a)), FastFuture.failed) - - def flatMap[B](f: A => Future[B])(implicit ec: ExecutionContext): Future[B] = - transformWith(f, FastFuture.failed) - - def filter(pred: A => Boolean)(implicit executor: ExecutionContext): Future[A] = - flatMap { r => - if (pred(r)) future - else throw new NoSuchElementException("Future.filter predicate is not satisfied") - } - - def foreach(f: A => Unit)(implicit ec: ExecutionContext): Unit = map(f) - - def transformWith[B](f: Try[A] => Future[B])(implicit executor: ExecutionContext): Future[B] = - transformWith(a => f(Success(a)), e => f(Failure(e))) - - def transformWith[B](s: A => Future[B], f: Throwable => Future[B])(implicit executor: ExecutionContext): Future[B] = { - def strictTransform[T](x: T, f: T => Future[B]) = - try f(x) - catch { case NonFatal(e) => ErrorFuture(e) } - - future match { - case FulfilledFuture(a) => strictTransform(a, s) - case ErrorFuture(e) => strictTransform(e, f) - case _ => future.value match { - case None => - val p = Promise[B]() - future.onComplete { - case Success(a) => p.completeWith(strictTransform(a, s)) - case Failure(e) => p.completeWith(strictTransform(e, f)) - } - p.future - case Some(Success(a)) => strictTransform(a, s) - case Some(Failure(e)) => strictTransform(e, f) - } - } - } - - def recover[B >: A](pf: PartialFunction[Throwable, B])(implicit ec: ExecutionContext): Future[B] = - transformWith(FastFuture.successful, t => if (pf.isDefinedAt(t)) FastFuture.successful(pf(t)) else future) - - def recoverWith[B >: A](pf: PartialFunction[Throwable, Future[B]])(implicit ec: ExecutionContext): Future[B] = - transformWith(FastFuture.successful, t => pf.applyOrElse(t, (_: Throwable) => future)) -} - -object FastFuture { - def apply[T](value: Try[T]): Future[T] = value match { - case Success(t) => FulfilledFuture(t) - case Failure(e) => ErrorFuture(e) - } - private[this] val _successful: Any => Future[Any] = FulfilledFuture.apply - def successful[T]: T => Future[T] = _successful.asInstanceOf[T => Future[T]] - val failed: Throwable => Future[Nothing] = ErrorFuture.apply - - private case class FulfilledFuture[+A](a: A) extends Future[A] { - def value = Some(Success(a)) - def onComplete[U](f: Try[A] => U)(implicit executor: ExecutionContext) = Future.successful(a).onComplete(f) - def isCompleted = true - def result(atMost: Duration)(implicit permit: CanAwait) = a - def ready(atMost: Duration)(implicit permit: CanAwait) = this - def transform[S](f: scala.util.Try[A] => scala.util.Try[S])( - implicit executor: scala.concurrent.ExecutionContext): scala.concurrent.Future[S] = - FastFuture(f(Success(a))) - def transformWith[S](f: scala.util.Try[A] => scala.concurrent.Future[S])( - implicit executor: scala.concurrent.ExecutionContext): scala.concurrent.Future[S] = - new FastFuture(this).transformWith(f) - } - private case class ErrorFuture(error: Throwable) extends Future[Nothing] { - def value = Some(Failure(error)) - def onComplete[U](f: Try[Nothing] => U)(implicit executor: ExecutionContext) = Future.failed(error).onComplete(f) - def isCompleted = true - def result(atMost: Duration)(implicit permit: CanAwait) = throw error - def ready(atMost: Duration)(implicit permit: CanAwait) = this - def transform[S](f: scala.util.Try[Nothing] => scala.util.Try[S])( - implicit executor: scala.concurrent.ExecutionContext): scala.concurrent.Future[S] = - FastFuture(f(Failure(error))) - def transformWith[S](f: scala.util.Try[Nothing] => scala.concurrent.Future[S])( - implicit executor: scala.concurrent.ExecutionContext): scala.concurrent.Future[S] = - new FastFuture(this).transformWith(f) - } - - implicit class EnhancedFuture[T](val future: Future[T]) extends AnyVal { - def fast: FastFuture[T] = new FastFuture[T](future) - } - - def sequence[T, M[_] <: TraversableOnce[_]](in: M[Future[T]])(implicit cbf: CanBuildFrom[M[Future[T]], T, M[T]], - executor: ExecutionContext): Future[M[T]] = - in.foldLeft(successful(cbf(in))) { - (fr, fa) => for (r <- fr.fast; a <- fa.asInstanceOf[Future[T]].fast) yield r += a - }.fast.map(_.result()) - - def fold[T, R](futures: TraversableOnce[Future[T]])(zero: R)(f: (R, T) => R)( - implicit executor: ExecutionContext): Future[R] = - if (futures.isEmpty) successful(zero) - else sequence(futures).fast.map(_.foldLeft(zero)(f)) - - def reduce[T, R >: T](futures: TraversableOnce[Future[T]])(op: (R, T) => R)( - implicit executor: ExecutionContext): Future[R] = - if (futures.isEmpty) failed(new NoSuchElementException("reduce attempted on empty collection")) - else sequence(futures).fast.map(_.reduceLeft(op)) - - def traverse[A, B, M[_] <: TraversableOnce[_]](in: M[A])(fn: A => Future[B])( - implicit cbf: CanBuildFrom[M[A], B, M[B]], executor: ExecutionContext): Future[M[B]] = - in.foldLeft(successful(cbf(in))) { (fr, a) => - val fb = fn(a.asInstanceOf[A]) - for (r <- fr.fast; b <- fb.fast) yield r += b - }.fast.map(_.result()) -} diff --git a/http-core/src/main/scala-2.13+/org/apache/pekko/http/ccompat/MapHelpers.scala b/http-core/src/main/scala/org/apache/pekko/http/ccompat/MapHelpers.scala similarity index 100% rename from http-core/src/main/scala-2.13+/org/apache/pekko/http/ccompat/MapHelpers.scala rename to http-core/src/main/scala/org/apache/pekko/http/ccompat/MapHelpers.scala diff --git a/http-core/src/main/scala-2.13+/org/apache/pekko/http/ccompat/imm/package.scala b/http-core/src/main/scala/org/apache/pekko/http/ccompat/imm/package.scala similarity index 100% rename from http-core/src/main/scala-2.13+/org/apache/pekko/http/ccompat/imm/package.scala rename to http-core/src/main/scala/org/apache/pekko/http/ccompat/imm/package.scala diff --git a/http-core/src/main/scala-2.13+/org/apache/pekko/http/ccompat/package.scala b/http-core/src/main/scala/org/apache/pekko/http/ccompat/package.scala similarity index 100% rename from http-core/src/main/scala-2.13+/org/apache/pekko/http/ccompat/package.scala rename to http-core/src/main/scala/org/apache/pekko/http/ccompat/package.scala diff --git a/http-core/src/main/scala/org/apache/pekko/http/scaladsl/model/HttpMessage.scala b/http-core/src/main/scala/org/apache/pekko/http/scaladsl/model/HttpMessage.scala index 43b307b3e..447aa2a15 100644 --- a/http-core/src/main/scala/org/apache/pekko/http/scaladsl/model/HttpMessage.scala +++ b/http-core/src/main/scala/org/apache/pekko/http/scaladsl/model/HttpMessage.scala @@ -30,7 +30,7 @@ import pekko.Done import pekko.actor.ClassicActorSystemProvider import org.parboiled2.CharUtils import pekko.util.{ ByteString, HashCode, OptionVal } -import pekko.http.ccompat.{ pre213, since213 } +import pekko.http.ccompat.since213 import pekko.http.impl.util._ import pekko.http.javadsl.{ model => jm } import pekko.http.scaladsl.util.FastFuture._ @@ -82,7 +82,6 @@ sealed trait HttpMessage extends jm.HttpMessage { entity.discardBytes()(SystemMaterializer(system).materializer) /** Returns a copy of this message with the list of headers set to the given ones. */ - @pre213 def withHeaders(headers: HttpHeader*): Self = withHeaders(headers.toList) /** Returns a copy of this message with the list of headers set to the given ones. */ @@ -97,7 +96,6 @@ sealed trait HttpMessage extends jm.HttpMessage { * Returns a new message that contains all of the given default headers which didn't already * exist (by case-insensitive header name) in this message. */ - @pre213 def withDefaultHeaders(defaultHeaders: HttpHeader*): Self = withDefaultHeaders(defaultHeaders.toList) @since213 diff --git a/http-core/src/main/scala/org/apache/pekko/http/scaladsl/model/headers/CacheDirective.scala b/http-core/src/main/scala/org/apache/pekko/http/scaladsl/model/headers/CacheDirective.scala index 3152c8c07..08b76230f 100644 --- a/http-core/src/main/scala/org/apache/pekko/http/scaladsl/model/headers/CacheDirective.scala +++ b/http-core/src/main/scala/org/apache/pekko/http/scaladsl/model/headers/CacheDirective.scala @@ -20,7 +20,7 @@ import scala.annotation.{ tailrec, varargs } import scala.collection.immutable import pekko.http.impl.util._ import pekko.http.javadsl.{ model => jm } -import pekko.http.ccompat.{ pre213, since213 } +import pekko.http.ccompat.since213 sealed trait CacheDirective extends Renderable with jm.headers.CacheDirective { def value: String @@ -93,7 +93,6 @@ object CacheDirectives { * http://tools.ietf.org/html/rfc7234#section-5.2.1.4 */ case object `no-cache` extends SingletonValueRenderable with RequestDirective with ResponseDirective { - @pre213 def apply(fieldNames: String*): `no-cache` = new `no-cache`(immutable.Seq(fieldNames: _*)) @since213 @@ -148,7 +147,6 @@ object CacheDirectives { */ final case class `private`(fieldNames: immutable.Seq[String]) extends FieldNamesDirective with ResponseDirective object `private` { - @pre213 def apply(fieldNames: String*): `private` = new `private`(immutable.Seq(fieldNames: _*)) @since213 def apply(): `private` = new `private`(immutable.Seq.empty) diff --git a/http-core/src/main/scala/org/apache/pekko/http/scaladsl/model/headers/LanguageRange.scala b/http-core/src/main/scala/org/apache/pekko/http/scaladsl/model/headers/LanguageRange.scala index 56bdfbfe9..94eb9d3f5 100644 --- a/http-core/src/main/scala/org/apache/pekko/http/scaladsl/model/headers/LanguageRange.scala +++ b/http-core/src/main/scala/org/apache/pekko/http/scaladsl/model/headers/LanguageRange.scala @@ -20,7 +20,7 @@ import pekko.http.impl.util._ import pekko.http.scaladsl.model.WithQValue import pekko.http.javadsl.{ model => jm } import pekko.http.impl.util.JavaMapping.Implicits._ -import pekko.http.ccompat.{ pre213, since213 } +import pekko.http.ccompat.since213 sealed trait LanguageRange extends jm.headers.LanguageRange with ValueRenderable with WithQValue[LanguageRange] { def qValue: Float @@ -82,7 +82,6 @@ object Language { val tags = compoundTag.split('-') new Language(tags.head, immutable.Seq(tags.tail: _*)) } else new Language(compoundTag, immutable.Seq.empty) - @pre213 def apply(primaryTag: String, subTags: String*): Language = new Language(primaryTag, immutable.Seq(subTags: _*)) @since213 diff --git a/http-core/src/main/scala/org/apache/pekko/http/scaladsl/model/headers/LinkValue.scala b/http-core/src/main/scala/org/apache/pekko/http/scaladsl/model/headers/LinkValue.scala index 449be0cc8..abecb0d7b 100644 --- a/http-core/src/main/scala/org/apache/pekko/http/scaladsl/model/headers/LinkValue.scala +++ b/http-core/src/main/scala/org/apache/pekko/http/scaladsl/model/headers/LinkValue.scala @@ -21,7 +21,7 @@ import pekko.http.scaladsl.model._ import pekko.http.javadsl.{ model => jm } import pekko.http.impl.util.JavaMapping.Implicits._ import UriRendering.UriRenderer -import pekko.http.ccompat.{ pre213, since213 } +import pekko.http.ccompat.since213 final case class LinkValue(uri: Uri, params: immutable.Seq[LinkParam]) extends jm.headers.LinkValue with ValueRenderable { @@ -36,7 +36,6 @@ final case class LinkValue(uri: Uri, params: immutable.Seq[LinkParam]) extends j } object LinkValue { - @pre213 def apply(uri: Uri, params: LinkParam*): LinkValue = apply(uri, immutable.Seq(params: _*)) @since213 def apply(uri: Uri, firstParam: LinkParam, otherParams: LinkParam*): LinkValue = apply(uri, firstParam +: otherParams) diff --git a/http-core/src/main/scala/org/apache/pekko/http/scaladsl/model/headers/headers.scala b/http-core/src/main/scala/org/apache/pekko/http/scaladsl/model/headers/headers.scala index 5f639e39e..d51ed3fb5 100644 --- a/http-core/src/main/scala/org/apache/pekko/http/scaladsl/model/headers/headers.scala +++ b/http-core/src/main/scala/org/apache/pekko/http/scaladsl/model/headers/headers.scala @@ -29,7 +29,7 @@ import scala.annotation.tailrec import scala.collection.immutable import org.parboiled2.util.Base64 import pekko.event.Logging -import pekko.http.ccompat.{ pre213, since213 } +import pekko.http.ccompat.since213 import pekko.http.impl.util._ import pekko.http.impl.model.parser.CharacterClasses.`attr-char` import pekko.http.javadsl.{ model => jm } @@ -147,7 +147,6 @@ import pekko.http.impl.util.JavaMapping.Implicits._ // https://tools.ietf.org/html/rfc7231#section-5.3.2 object Accept extends ModeledCompanion[Accept] { - @pre213 def apply(mediaRanges: MediaRange*): Accept = apply(immutable.Seq(mediaRanges: _*)) @since213 @@ -185,7 +184,6 @@ final case class `Accept-Charset`(charsetRanges: immutable.Seq[HttpCharsetRange] // https://tools.ietf.org/html/rfc7231#section-5.3.4 object `Accept-Encoding` extends ModeledCompanion[`Accept-Encoding`] { - @pre213 def apply(encodings: HttpEncodingRange*): `Accept-Encoding` = apply(immutable.Seq(encodings: _*)) @since213 @@ -226,7 +224,6 @@ final case class `Accept-Language`(languages: immutable.Seq[LanguageRange]) exte // https://tools.ietf.org/html/rfc7233#section-2.3 object `Accept-Ranges` extends ModeledCompanion[`Accept-Ranges`] { - @pre213 def apply(rangeUnits: RangeUnit*): `Accept-Ranges` = apply(immutable.Seq(rangeUnits: _*)) @since213 @@ -257,7 +254,6 @@ final case class `Access-Control-Allow-Credentials`(allow: Boolean) // https://www.w3.org/TR/cors/#access-control-allow-headers-response-header object `Access-Control-Allow-Headers` extends ModeledCompanion[`Access-Control-Allow-Headers`] { - @pre213 def apply(headers: String*): `Access-Control-Allow-Headers` = apply(immutable.Seq(headers: _*)) @since213 @@ -277,7 +273,6 @@ final case class `Access-Control-Allow-Headers`(headers: immutable.Seq[String]) // https://www.w3.org/TR/cors/#access-control-allow-methods-response-header object `Access-Control-Allow-Methods` extends ModeledCompanion[`Access-Control-Allow-Methods`] { - @pre213 def apply(methods: HttpMethod*): `Access-Control-Allow-Methods` = apply(immutable.Seq(methods: _*)) @since213 @@ -318,7 +313,6 @@ final case class `Access-Control-Allow-Origin` private (range: HttpOriginRange) // https://www.w3.org/TR/cors/#access-control-expose-headers-response-header object `Access-Control-Expose-Headers` extends ModeledCompanion[`Access-Control-Expose-Headers`] { - @pre213 def apply(headers: String*): `Access-Control-Expose-Headers` = apply(immutable.Seq(headers: _*)) @since213 @@ -346,7 +340,6 @@ final case class `Access-Control-Max-Age`(deltaSeconds: Long) extends jm.headers // https://www.w3.org/TR/cors/#access-control-request-headers-request-header object `Access-Control-Request-Headers` extends ModeledCompanion[`Access-Control-Request-Headers`] { - @pre213 def apply(headers: String*): `Access-Control-Request-Headers` = apply(immutable.Seq(headers: _*)) @since213 @@ -381,7 +374,6 @@ final case class Age(deltaSeconds: Long) extends jm.headers.Age with ResponseHea // https://tools.ietf.org/html/rfc7231#section-7.4.1 object Allow extends ModeledCompanion[Allow] { - @pre213 def apply(methods: HttpMethod*): Allow = apply(immutable.Seq(methods: _*)) @since213 @@ -564,7 +556,6 @@ final case class `Content-Type` private[pekko] (contentType: ContentType) extend object Cookie extends ModeledCompanion[Cookie] { def apply(first: HttpCookiePair, more: HttpCookiePair*): Cookie = apply(immutable.Seq(first +: more: _*)) def apply(name: String, value: String): Cookie = apply(HttpCookiePair(name, value)) - @pre213 def apply(values: (String, String)*): Cookie = apply(values.map(HttpCookiePair(_)).toList) @since213 def apply(first: (String, String), more: (String, String)*): Cookie = apply((first +: more).map(HttpCookiePair(_))) @@ -716,7 +707,6 @@ final case class `Last-Modified`(date: DateTime) extends jm.headers.LastModified object Link extends ModeledCompanion[Link] { def apply(uri: Uri, first: LinkParam, more: LinkParam*): Link = apply(immutable.Seq(LinkValue(uri, first +: more.toList))) - @pre213 def apply(values: LinkValue*): Link = apply(immutable.Seq(values: _*)) @since213 def apply(firstValue: LinkValue, otherValues: LinkValue*): Link = apply(firstValue +: otherValues) @@ -744,7 +734,6 @@ final case class Location(uri: Uri) extends jm.headers.Location with ResponseHea // https://tools.ietf.org/html/rfc6454#section-7 object Origin extends ModeledCompanion[Origin] { - @pre213 def apply(origins: HttpOrigin*): Origin = apply(immutable.Seq(origins: _*)) @since213 def apply(firstOrigin: HttpOrigin, otherOrigins: HttpOrigin*): Origin = apply(firstOrigin +: otherOrigins) diff --git a/http-core/src/main/scala-2.13+/org/apache/pekko/http/scaladsl/util/FastFuture.scala b/http-core/src/main/scala/org/apache/pekko/http/scaladsl/util/FastFuture.scala similarity index 100% rename from http-core/src/main/scala-2.13+/org/apache/pekko/http/scaladsl/util/FastFuture.scala rename to http-core/src/main/scala/org/apache/pekko/http/scaladsl/util/FastFuture.scala diff --git a/http-core/src/test/scala/io/pekko/integrationtest/http/HttpModelIntegrationSpec.scala b/http-core/src/test/scala/io/pekko/integrationtest/http/HttpModelIntegrationSpec.scala index 9cf55f763..56fb64529 100644 --- a/http-core/src/test/scala/io/pekko/integrationtest/http/HttpModelIntegrationSpec.scala +++ b/http-core/src/test/scala/io/pekko/integrationtest/http/HttpModelIntegrationSpec.scala @@ -21,7 +21,6 @@ import org.scalatest.BeforeAndAfterAll import org.apache.pekko import pekko.util.ByteString import pekko.actor.ActorSystem -import pekko.http.ccompat._ // required for Scala 2.12 compilation import pekko.http.scaladsl.model._ import pekko.stream.scaladsl._ import pekko.testkit._ diff --git a/http-scalafix/README.md b/http-scalafix/README.md index 3bc3bc429..035254586 100644 --- a/http-scalafix/README.md +++ b/http-scalafix/README.md @@ -11,6 +11,3 @@ The setup of the scalafix module roughly follows the example in https://github.c * run `scalafixEnable` on the sbt shell (this will unfortunately require a complete rebuild afterwards) * run `set scalacOptions in ThisBuild += "-P:semanticdb:synthetics:on"` to allow access to synthetics * e.g. run `docs/scalafixAll MigrateToServerBuilder` - -*Note:* There's some weird stuff going on regarding cross-publishing. If running the rule fails with a weird error, try switching to Scala 2.12 first with `++2.12.11` (or -whatever is now the current version). diff --git a/http-tests/src/test/scala-2.13-/main/org/apache/pekko/http/scaladsl/server/util/package.scala b/http-tests/src/test/scala-2.13-/main/org/apache/pekko/http/scaladsl/server/util/package.scala deleted file mode 100644 index a19bed487..000000000 --- a/http-tests/src/test/scala-2.13-/main/org/apache/pekko/http/scaladsl/server/util/package.scala +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * license agreements; and to You under the Apache License, version 2.0: - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * This file is part of the Apache Pekko project, which was derived from Akka. - */ - -/* - * Copyright (C) 2009-2022 Lightbend Inc. - */ - -package org.apache.pekko.http.scaladsl.server - -package object util { - type VarArgsFunction1[-T, +U] = (T*) => U -} diff --git a/http-tests/src/test/scala-2.13-/src/main/org/apache/pekko/http/ccompat/ImplicitUtils.scala b/http-tests/src/test/scala-2.13-/src/main/org/apache/pekko/http/ccompat/ImplicitUtils.scala deleted file mode 100644 index 2ceafb7f8..000000000 --- a/http-tests/src/test/scala-2.13-/src/main/org/apache/pekko/http/ccompat/ImplicitUtils.scala +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * license agreements; and to You under the Apache License, version 2.0: - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * This file is part of the Apache Pekko project, which was derived from Akka. - */ - -/* - * Copyright (C) 2009-2022 Lightbend Inc. - */ - -package org.apache.pekko.http.ccompat - -object ImplicitUtils diff --git a/http-tests/src/test/scala-2.13+/org/apache/pekko/http/scaladsl/server/util/VarArgsFunction1.scala b/http-tests/src/test/scala/org/apache/pekko/http/scaladsl/server/util/VarArgsFunction1.scala similarity index 100% rename from http-tests/src/test/scala-2.13+/org/apache/pekko/http/scaladsl/server/util/VarArgsFunction1.scala rename to http-tests/src/test/scala/org/apache/pekko/http/scaladsl/server/util/VarArgsFunction1.scala diff --git a/http/src/main/scala/org/apache/pekko/http/scaladsl/server/directives/FormFieldDirectives.scala b/http/src/main/scala/org/apache/pekko/http/scaladsl/server/directives/FormFieldDirectives.scala index aa5977869..d4873255c 100644 --- a/http/src/main/scala/org/apache/pekko/http/scaladsl/server/directives/FormFieldDirectives.scala +++ b/http/src/main/scala/org/apache/pekko/http/scaladsl/server/directives/FormFieldDirectives.scala @@ -27,7 +27,6 @@ import scala.collection.immutable import scala.concurrent.Future import scala.util.{ Failure, Success } import BasicDirectives._ -import pekko.http.ccompat.pre213 import pekko.http.ccompat.since213 /** diff --git a/http/src/main/scala/org/apache/pekko/http/scaladsl/server/directives/RespondWithDirectives.scala b/http/src/main/scala/org/apache/pekko/http/scaladsl/server/directives/RespondWithDirectives.scala index 97fe3ffd8..beed18cd4 100644 --- a/http/src/main/scala/org/apache/pekko/http/scaladsl/server/directives/RespondWithDirectives.scala +++ b/http/src/main/scala/org/apache/pekko/http/scaladsl/server/directives/RespondWithDirectives.scala @@ -47,7 +47,6 @@ trait RespondWithDirectives { * * @group response */ - @pre213 def respondWithHeaders(responseHeaders: HttpHeader*): Directive0 = respondWithHeaders(responseHeaders.toList) @@ -69,7 +68,6 @@ trait RespondWithDirectives { * * @group response */ - @pre213 def respondWithDefaultHeaders(responseHeaders: HttpHeader*): Directive0 = respondWithDefaultHeaders(responseHeaders.toList) diff --git a/parsing/src/main/scala-2/org/apache/pekko/http/ccompat/pre213macro.scala b/parsing/src/main/scala-2/org/apache/pekko/http/ccompat/pre213macro.scala deleted file mode 100644 index 1edf051ef..000000000 --- a/parsing/src/main/scala-2/org/apache/pekko/http/ccompat/pre213macro.scala +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * license agreements; and to You under the Apache License, version 2.0: - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * This file is part of the Apache Pekko project, which was derived from Akka. - */ - -/* - * Copyright (C) 2019-2022 Lightbend Inc. - */ - -package org.apache.pekko.http.ccompat - -import scala.annotation.StaticAnnotation -import scala.language.experimental.macros -import scala.reflect.macros.blackbox.Context - -object pre213macro { - def impl(c: Context)(annottees: c.Expr[Any]*): c.Expr[Any] = annottees match { - case Seq(method) => - import c.universe._ - if (scala.util.Properties.versionNumberString.startsWith("2.13")) - c.Expr[Nothing](EmptyTree) - else - method - case _ => - c.abort(c.enclosingPosition, "Please annotate single expressions") - } -} -class pre213 extends StaticAnnotation { - def macroTransform(annottees: Any*): Any = macro pre213macro.impl -} diff --git a/parsing/src/main/scala-3/org/apache/pekko/http/ccompat/pre213macro.scala b/parsing/src/main/scala-3/org/apache/pekko/http/ccompat/pre213macro.scala deleted file mode 100644 index 21dd8a0c2..000000000 --- a/parsing/src/main/scala-3/org/apache/pekko/http/ccompat/pre213macro.scala +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * license agreements; and to You under the Apache License, version 2.0: - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * This file is part of the Apache Pekko project, which was derived from Akka. - */ - -/* - * Copyright (C) 2019-2022 Lightbend Inc. - */ - -package org.apache.pekko.http.ccompat - -import scala.annotation.StaticAnnotation - -// FIXME: need to implement or we will resurrect some ugly things (or remove 2.12 support) -class pre213 extends StaticAnnotation diff --git a/project/Common.scala b/project/Common.scala index da0762a30..0b76bf1e0 100644 --- a/project/Common.scala +++ b/project/Common.scala @@ -48,9 +48,6 @@ object Common extends AutoPlugin { Global / parallelExecution := sys.props.getOrElse("pekko.http.parallelExecution", "true") != "false") val javacTarget: String = "17" - def onlyAfterScala212[T](values: Seq[T]): Def.Initialize[Seq[T]] = Def.setting { - if (scalaMinorVersion.value >= 12) values else Seq.empty[T] - } def onlyOnScala2[T](values: Seq[T]): Def.Initialize[Seq[T]] = Def.setting { if (scalaVersion.value.startsWith("3")) Seq.empty[T] else values } diff --git a/project/Dependencies.scala b/project/Dependencies.scala index 0d627d346..d3d64a3c2 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -33,10 +33,9 @@ object Dependencies { val scalafixVersion = _root_.scalafix.sbt.BuildInfo.scalafixVersion // grab from plugin - val scala212Version = "2.12.20" val scala213Version = "2.13.16" val scala3Version = "3.3.6" - val allScalaVersions = Seq(scala213Version, scala212Version, scala3Version) + val allScalaVersions = Seq(scala213Version, scala3Version) val Versions = Seq( crossScalaVersions := allScalaVersions, diff --git a/project/Pre213Preprocessor.scala b/project/Pre213Preprocessor.scala deleted file mode 100644 index 79a91c77a..000000000 --- a/project/Pre213Preprocessor.scala +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * license agreements; and to You under the Apache License, version 2.0: - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * This file is part of the Apache Pekko project, which was derived from Akka. - */ - -import sbt._ -import Keys._ - -object Pre213Preprocessor extends AutoPlugin { - val pre213Files = settingKey[Seq[String]]("files that should be edited for pre213 annotation") - - val pattern = """(?s)@pre213.*?@since213""".r - - override def projectSettings: Seq[Def.Setting[_]] = { - Compile / sources := { - if (scalaVersion.value.startsWith("3")) { - val filter: File => Boolean = - f => pre213Files.value.exists(suffix => f.getAbsolutePath.replace("\\", "//").endsWith(suffix)) - (Compile / sources).value.map { s => - if (filter(s)) { - val data = IO.read(s) - val targetFile = sourceManaged.value / s.getName - val newData = pattern.replaceAllIn(data, "@since213") - IO.write(targetFile, newData) - targetFile - } else s - } - } else (Compile / sources).value - } - } -}