Skip to content

Commit

Permalink
add scala-styled lambdas rendering, closes #367 (#373)
Browse files Browse the repository at this point in the history
  • Loading branch information
Ivoyaa authored Mar 14, 2023
1 parent dc1b9cd commit c0cb7cf
Show file tree
Hide file tree
Showing 4 changed files with 75 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,14 @@ package izumi.reflect.macrortti

import izumi.reflect.internal.fundamentals.functional.{Renderable, WithRenderableSyntax}
import izumi.reflect.internal.fundamentals.platform.language.unused
import izumi.reflect.macrortti.LightTypeTagInheritance.{tpeAny, tpeAnyRef, tpeNothing, tpeObject}
import izumi.reflect.macrortti.LightTypeTagRef.SymName.SymLiteral
import izumi.reflect.macrortti.LightTypeTagRef._

trait LTTRenderables extends Serializable with WithRenderableSyntax {

def r_SymName(sym: SymName, hasPrefix: Boolean): String

def prefixSplitter: String = "::"

implicit lazy val r_LightTypeTag: Renderable[LightTypeTagRef] = new Renderable[LightTypeTagRef] {
Expand Down Expand Up @@ -109,7 +111,7 @@ trait LTTRenderables extends Serializable with WithRenderableSyntax {
case t if t > 0 =>
s"${value.depth}:${value.index}"
// FIXME so-called "debug" view doesn't display all the data here which could lead to confusion when "debugging"
// s"[${value.arity}]${value.depth}:${value.index}"
// s"[${value.arity}]${value.depth}:${value.index}"
}
}
}
Expand Down Expand Up @@ -201,8 +203,10 @@ object LTTRenderables {
}
}

object Long extends Long

// print package names
object Long extends LTTRenderables {
private[LTTRenderables] trait Long extends LTTRenderables {
override def r_SymName(sym: SymName, hasPrefix: Boolean): String = {
if (hasPrefix) {
Short.r_SymName(sym, hasPrefix)
Expand All @@ -217,8 +221,8 @@ object LTTRenderables {
private[macrortti] def renderDb(db: Map[_ <: AbstractReference, Set[_ <: AbstractReference]]): String = {
import izumi.reflect.internal.fundamentals.platform.strings.IzString._
db.toList.sortBy(_._1)(OrderingAbstractReferenceInstance).map {
case (k, v) => s"${k.repr} -> ${v.toList.sorted(OrderingAbstractReferenceInstance).map(_.repr).niceList(prefix = "* ").shift(2)}"
}.niceList()
case (k, v) => s"${k.repr} -> ${v.toList.sorted(OrderingAbstractReferenceInstance).map(_.repr).niceList(prefix = "* ").shift(2)}"
}.niceList()
}
}

Expand All @@ -227,7 +231,59 @@ object LTTRenderables {
override def r_SymName(sym: SymName, hasPrefix: Boolean): String = {
Long.r_SymName(sym, hasPrefix)
}

override def prefixSplitter: String = "."
}

}
object ScalaStyledLambdas extends Long {

override def prefixSplitter: String = "."

override implicit lazy val r_LambdaParameterName: Renderable[SymName.LambdaParamName] = new Renderable[SymName.LambdaParamName] {
override def render(value: SymName.LambdaParamName): String = "_"
}

override implicit lazy val r_Lambda: Renderable[Lambda] = new Renderable[Lambda] {
override def render(value: Lambda): String = {
s"${value.output.render()}"
}
}

override implicit lazy val r_Variance: Renderable[Variance] = new Renderable[Variance] {
override def render(value: Variance): String = value match {
case Variance.Invariant => ""
case Variance.Contravariant => "-"
case Variance.Covariant => "+"
}
}

override implicit lazy val r_NameRefRenderer: Renderable[NameReference] = new Renderable[NameReference] {
override def render(value: NameReference): String = {
val r = r_SymName(value.ref, value.prefix.isDefined)

val rr = value.boundaries match {
case _: Boundaries.Defined =>
s"$r ${value.boundaries.render()}"
case Boundaries.Empty =>
r
}

value.prefix match {
case Some(p) =>
s"${p.render()}$prefixSplitter$rr"
case None =>
rr
}
}
}

override implicit lazy val r_Boundaries: Renderable[Boundaries] = new Renderable[Boundaries] {
override def render(value: Boundaries): String = value match {
case Boundaries.Defined(bottom, top) if bottom == tpeNothing => s"<: ${top.render()}"
case Boundaries.Defined(bottom, top) if top == tpeAny || top == tpeAnyRef || top == tpeObject => s">: ${bottom.render()}"
case Boundaries.Defined(bottom, top) => s">: ${bottom.render()} <: ${top.render()}"
case Boundaries.Empty => ""
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,11 @@ private[macrortti] trait LTTSyntax {
getName(r => LTTRenderables.Long.r_SymName(r.symName, hasPrefix = false))
}

protected[this] final def scalaStyledNameImpl: String = {
import izumi.reflect.macrortti.LTTRenderables.ScalaStyledLambdas._
(this: LightTypeTagRef).render()
}

@deprecated(
"Produces Scala version dependent output, with incorrect prefixes for types with value prefixes. Use `longNameWithPrefix` instead, or `longNameInternalSymbol` for old behavior",
"2.2.2"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,14 @@ abstract class LightTypeTag private[reflect] (
ref.longNameInternalSymbol
}

/**
* Fully-qualified rendering of a type, including packages and prefix types.
* Traditional Scala notation for lambdas, e.g. scala.util.Either[+scala.Int,+_]
*/
def scalaStyledName: String = {
ref.scalaStyledName
}

@deprecated(
"Produces Scala version dependent output, with incorrect prefixes for types with value prefixes. Use `longNameWithPrefix` instead, or `longNameInternalSymbol` for old behavior",
"2.2.2"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ sealed trait LightTypeTagRef extends LTTSyntax with Serializable {
* Use [[toString]] for a rendering that omits package names
*/
final def repr: String = this.reprImpl
final def scalaStyledName: String = this.scalaStyledNameImpl
final def shortName: String = this.shortNameImpl
final def longNameWithPrefix: String = this.longNameWithPrefixImpl
final def longNameInternalSymbol: String = this.longNameInternalSymbolImpl
Expand Down

0 comments on commit c0cb7cf

Please sign in to comment.