-
Notifications
You must be signed in to change notification settings - Fork 90
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #198 from rreckel/develop
- Loading branch information
Showing
4 changed files
with
167 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
package sbtbuildinfo | ||
|
||
case class Scala3CaseClassRenderer(options: Seq[BuildInfoOption], pkg: String, obj: String) extends Scala3Renderer { | ||
override def fileType = BuildInfoType.Source | ||
override def extension = "scala" | ||
|
||
val traitNames = options.collect{case BuildInfoOption.Traits(ts @ _*) => ts}.flatten | ||
val objTraits = if (traitNames.isEmpty) "" else "extends " ++ traitNames.mkString(" with ") | ||
|
||
// It is safe to add `import scala.Predef` even though we need to keep `-Ywarn-unused-import` in mind | ||
// because we always generate code that has a reference to `String`. If the "base" generated code were to be | ||
// changed and no longer contain a reference to `String`, we would need to remove `import scala.Predef` and | ||
// fully qualify every reference. Note it is NOT safe to use `import scala._` because of the possibility of | ||
// the project using `-Ywarn-unused-import` because we do not always generated references that are part of | ||
// `scala` such as `scala.Option`. | ||
val importScalaPredef = options.contains(BuildInfoOption.ImportScalaPredef) | ||
def header = List( | ||
"// $COVERAGE-OFF$", | ||
s"package $pkg", | ||
"" | ||
) | ||
val imports = if (importScalaPredef) List( | ||
"import scala.Predef.*", | ||
"" | ||
) else Nil | ||
val generateComment = List( | ||
s"/** This file was generated by sbt-buildinfo. */" | ||
) | ||
|
||
def footer = List("// $COVERAGE-ON$") | ||
|
||
override def renderKeys(buildInfoResults: Seq[BuildInfoResult]) = | ||
header ++ imports ++ generateComment ++ | ||
caseClassDefinitionBegin ++ | ||
buildInfoResults.flatMap(caseClassParameter).mkString(",\n").split("\n") ++ | ||
caseClassDefinitionEnd ++ | ||
toMapLines(buildInfoResults) ++ | ||
toJsonLines ++ | ||
caseClassEnd ++ | ||
List("") ++ | ||
caseObjectLine(buildInfoResults) ++ | ||
footer | ||
|
||
private def caseClassDefinitionBegin = List( | ||
withPkgPriv(s"case class $obj(") | ||
) | ||
|
||
private def caseClassParameter(r: BuildInfoResult): Seq[String] = { | ||
val typeDecl = getType(r.typeExpr) getOrElse "scala.Any" | ||
|
||
List( | ||
s" ${r.identifier}: $typeDecl" | ||
) | ||
} | ||
|
||
private def caseClassDefinitionEnd = List(s") $objTraits {", "") | ||
private def caseClassEnd = List("}") | ||
|
||
private def caseObjectLine(buildInfoResults: Seq[BuildInfoResult]) = List( | ||
withPkgPriv(s"case object $obj {"), | ||
s" def apply(): $obj = new $obj(${buildInfoResults.map(r => s"\n ${r.identifier} = ${quote(r.value)}").mkString(",")})", | ||
s" val get = apply()", | ||
s" val value = apply()", | ||
s"}" | ||
) | ||
} |
71 changes: 71 additions & 0 deletions
71
src/main/scala/sbtbuildinfo/Scala3CaseObjectRenderer.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
package sbtbuildinfo | ||
|
||
case class Scala3CaseObjectRenderer(options: Seq[BuildInfoOption], pkg: String, obj: String) extends Scala3Renderer { | ||
|
||
override def fileType = BuildInfoType.Source | ||
override def extension = "scala" | ||
val traitNames = options.collect{case BuildInfoOption.Traits(ts @ _*) => ts}.flatten | ||
val objTraits = if (traitNames.isEmpty) "" else " extends " ++ traitNames.mkString(" with ") | ||
val constantValue = options.contains(BuildInfoOption.ConstantValue) | ||
|
||
// It is safe to add `import scala.Predef` even though we need to keep `-Ywarn-unused-import` in mind | ||
// because we always generate code that has a reference to `String`. If the "base" generated code were to be | ||
// changed and no longer contain a reference to `String`, we would need to remove `import scala.Predef` and | ||
// fully qualify every reference. Note it is NOT safe to use `import scala._` because of the possibility of | ||
// the project using `-Ywarn-unused-import` because we do not always generated references that are part of | ||
// `scala` such as `scala.Option`. | ||
val importScalaPredef = options.contains(BuildInfoOption.ImportScalaPredef) | ||
def header = List( | ||
"// $COVERAGE-OFF$", | ||
s"package $pkg", | ||
"" | ||
) | ||
val imports = if (importScalaPredef) List( | ||
"import scala.Predef.*", | ||
"" | ||
) else Nil | ||
val objectHeader = List( | ||
s"/** This object was generated by sbt-buildinfo. */", | ||
withPkgPriv(s"case object $obj$objTraits {") | ||
) | ||
|
||
def footer = List("}", "// $COVERAGE-ON$") | ||
|
||
override def renderKeys(buildInfoResults: Seq[BuildInfoResult]) = | ||
header ++ imports ++ objectHeader ++ | ||
buildInfoResults.flatMap(line) ++ | ||
Seq(toStringLines(buildInfoResults)) ++ | ||
toMapLines(buildInfoResults) ++ | ||
toJsonLines ++ | ||
footer | ||
|
||
private val constantTypes = Set("scala.Int", "scala.Long", "scala.Double", "scala.Boolean", "scala.Symbol", "String") | ||
|
||
private def line(result: BuildInfoResult): Seq[String] = { | ||
import result._ | ||
val (typeDecl, modifier) = | ||
getType(result.typeExpr) match { | ||
case Some(tp) if !constantValue || !constantTypes(tp) => | ||
(s": $tp", "") | ||
case _ if constantValue => | ||
("", "final ") | ||
case _ => | ||
("", "") | ||
} | ||
List( | ||
s" /** The value is ${quote(value)}. */", | ||
s" ${modifier}val $identifier$typeDecl = ${quote(value)}" | ||
) | ||
} | ||
|
||
def toStringLines(results: Seq[BuildInfoResult]): String = { | ||
val idents = results.map(_.identifier) | ||
val fmt = idents.map("%s: %%s" format _).mkString(", ") | ||
val vars = idents.mkString(", ") | ||
s""" override val toString: String = { | ||
| "$fmt".format( | ||
| $vars | ||
| ) | ||
| }""".stripMargin | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
package sbtbuildinfo | ||
|
||
abstract class Scala3Renderer extends ScalaRenderer { | ||
|
||
override protected def toJsonLines: Seq[String] = | ||
if (options contains BuildInfoOption.ToJson) | ||
List( | ||
"""| private def quote(x: scala.Any): String = "\"" + x + "\"" | ||
| private def toJsonValue[T <: Matchable](value: T): String = { | ||
| value match { | ||
| case elem: scala.collection.Seq[? <: Matchable] => elem.map(toJsonValue).mkString("[", ",", "]") | ||
| case elem: scala.Option[? <: Matchable] => elem.map(toJsonValue).getOrElse("null") | ||
| case elem: scala.collection.Map[?, ? <: Matchable] => elem.map { | ||
| case (k, v) => toJsonValue(k.toString) + ":" + toJsonValue(v) | ||
| }.mkString("{", ", ", "}") | ||
| case d: scala.Double => d.toString | ||
| case f: scala.Float => f.toString | ||
| case l: scala.Long => l.toString | ||
| case i: scala.Int => i.toString | ||
| case s: scala.Short => s.toString | ||
| case bool: scala.Boolean => bool.toString | ||
| case str: String => quote(str) | ||
| case other => quote(other.toString) | ||
| } | ||
| } | ||
| | ||
| val toJson: String = toJsonValue(toMap)""".stripMargin) | ||
else Nil | ||
} |