Introduce util-core to cross-compile util-logging

This commit is contained in:
Adrien Piquerez 2023-11-14 11:43:12 +01:00
parent bc3acd3bff
commit 73e3b43683
6 changed files with 61 additions and 36 deletions

View File

@ -257,12 +257,11 @@ lazy val bundledLauncherProj =
/* ** subproject declarations ** */
val collectionProj = (project in file("util-collection"))
.dependsOn(utilPosition)
.dependsOn(utilPosition, utilCore)
.settings(
name := "Collections",
testedBaseSettings,
utilCommonSettings,
Util.keywordsSettings,
libraryDependencies ++= Seq(sjsonNewScalaJson.value),
libraryDependencies ++= (CrossVersion.partialVersion(scalaVersion.value) match {
case Some((2, major)) if major <= 12 => Seq()
@ -335,9 +334,22 @@ lazy val utilPosition = (project in file("internal") / "util-position")
utilMimaSettings,
)
lazy val utilCore = project.in(file("internal") / "util-core")
.settings(
utilCommonSettings,
name := "Util Core",
libraryDependencies ++= {
if (scalaBinaryVersion.value.startsWith("2")) {
Seq("org.scala-lang" % "scala-reflect" % scalaVersion.value)
} else Seq.empty
},
Util.keywordsSettings,
utilMimaSettings
)
lazy val utilLogging = (project in file("internal") / "util-logging")
.enablePlugins(ContrabandPlugin, JsonCodecPlugin)
.dependsOn(utilInterface, collectionProj, coreMacrosProj)
.dependsOn(utilInterface, utilCore)
.settings(
utilCommonSettings,
name := "Util Logging",

View File

@ -0,0 +1,38 @@
/*
* sbt
* Copyright 2023, Scala center
* Copyright 2011 - 2022, Lightbend, Inc.
* Copyright 2008 - 2010, Mark Harrah
* Licensed under Apache License 2.0 (see LICENSE)
*/
package sbt.internal.util
import scala.language.experimental.macros
import scala.reflect.macros.blackbox
/** This is used to carry type information in JSON. */
final case class StringTypeTag[A](key: String) {
override def toString: String = key
}
object StringTypeTag {
/** Generates a StringTypeTag for any type at compile time. */
implicit def fast[A]: StringTypeTag[A] = macro impl[A]
def impl[A: c.WeakTypeTag](c: blackbox.Context): c.Tree = {
import c.universe._
val tpe = weakTypeOf[A]
def typeToString(tpe: Type): String = tpe match {
case TypeRef(_, sym, args) if args.nonEmpty =>
val typeCon = tpe.typeSymbol.fullName
val typeArgs = args map typeToString
s"""$typeCon[${typeArgs.mkString(",")}]"""
case _ => tpe.toString
}
val key = Literal(Constant(typeToString(tpe)))
q"new sbt.internal.util.StringTypeTag[$tpe]($key)"
}
}

View File

@ -5,7 +5,7 @@
* Licensed under Apache License 2.0 (see LICENSE)
*/
package sbt.internal.util.appmacro
package sbt.internal.util
final class StringTypeTag[A](val key: String):
override def toString(): String = key

View File

@ -9,15 +9,9 @@ package sbt.internal.util
import java.util.Locale
import scala.reflect.macros.blackbox
import scala.language.experimental.macros
object Util {
def makeList[T](size: Int, value: T): List[T] = List.fill(size)(value)
// def separateE[A, B](ps: Seq[Either[A, B]]): (Seq[A], Seq[B]) =
// separate(ps)(Types.idFun)
def separate[T, A, B](ps: Seq[T])(f: T => Either[A, B]): (Seq[A], Seq[B]) = {
val (a, b) = ps.foldLeft((Nil: Seq[A], Nil: Seq[B]))((xs, y) => prependEither(xs, f(y)))
(a.reverse, b.reverse)
@ -74,7 +68,4 @@ object Util {
implicit class AnyOps[A](private val value: A) extends AnyVal {
def some: Option[A] = (Some(value): Option[A])
}
// class Macro(val c: blackbox.Context) {
// def ignore(f: c.Tree): c.Expr[Unit] = c.universe.reify({ c.Expr[Any](f).splice; () })
// }
}

View File

@ -9,9 +9,8 @@ package sbt.internal.util
import sbt.internal.util.codec.JsonProtocol._
import sbt.util._
import scala.reflect.runtime.universe.TypeTag
import sjsonnew.JsonFormat
import sbt.internal.util.appmacro.StringTypeTag
import sbt.internal.util.StringTypeTag
private[sbt] trait MiniLogger {
def log[T](level: Level.Value, message: ObjectEvent[T]): Unit
@ -44,10 +43,7 @@ class ManagedLogger(
// send special event for success since it's not a real log level
override def success(message: => String): Unit = {
if (terminal.fold(true)(_.isSuccessEnabled)) {
infoEvent[SuccessEvent](SuccessEvent(message))(
implicitly[JsonFormat[SuccessEvent]],
StringTypeTag[SuccessEvent],
)
infoEvent[SuccessEvent](SuccessEvent(message))
}
}

View File

@ -12,7 +12,7 @@ import org.apache.logging.log4j.core.layout.PatternLayout
import org.apache.logging.log4j.core.{ LoggerContext => XLoggerContext }
import org.apache.logging.log4j.{ LogManager => XLogManager }
import sbt.internal.util.{ Appender, ManagedLogger, TraceEvent, SuccessEvent, Util }
import sbt.internal.util.appmacro.StringTypeTag
import sbt.internal.util.StringTypeTag
import java.util.concurrent.ConcurrentHashMap
import scala.collection.concurrent
@ -44,23 +44,14 @@ sealed abstract class LogExchange {
()
}
// Construct these StringTypeTags manually, because they're used at the very startup of sbt
// and we'll try not to initialize the universe by using the StringTypeTag.apply that requires a TypeTag
// A better long-term solution could be to make StringTypeTag.apply a macro.
lazy val stringTypeTagThrowable = StringTypeTag.manually[Throwable]("java.lang.Throwable")
lazy val stringTypeTagTraceEvent =
StringTypeTag.manually[TraceEvent]("sbt.internal.util.TraceEvent")
lazy val stringTypeTagSuccessEvent =
StringTypeTag.manually[SuccessEvent]("sbt.internal.util.SuccessEvent")
private[sbt] def initStringCodecs(): Unit = {
import sbt.internal.util.codec.SuccessEventShowLines._
import sbt.internal.util.codec.ThrowableShowLines._
import sbt.internal.util.codec.TraceEventShowLines._
registerStringCodecByStringTypeTag(stringTypeTagThrowable)
registerStringCodecByStringTypeTag(stringTypeTagTraceEvent)
registerStringCodecByStringTypeTag(stringTypeTagSuccessEvent)
registerStringCodec[Throwable]
registerStringCodec[TraceEvent]
registerStringCodec[SuccessEvent]
}
// This is a dummy layout to avoid casting error during PatternLayout.createDefaultLayout()
@ -86,11 +77,8 @@ sealed abstract class LogExchange {
stringCodecs.getOrElseUpdate(tag, v).asInstanceOf[ShowLines[A]]
private[sbt] def registerStringCodec[A: ShowLines: StringTypeTag]: Unit = {
registerStringCodecByStringTypeTag(implicitly[StringTypeTag[A]])
}
private[sbt] def registerStringCodecByStringTypeTag[A: ShowLines](tag: StringTypeTag[A]): Unit = {
val ev = implicitly[ShowLines[A]]
val tag = implicitly[StringTypeTag[A]]
val _ = getOrElseUpdateStringCodec(tag.key, ev)
}