mirror of https://github.com/sbt/sbt.git
Port StringTypeTag
This commit is contained in:
parent
8d5355d274
commit
c724e83fd1
|
|
@ -1,27 +0,0 @@
|
|||
/*
|
||||
* sbt
|
||||
* Copyright 2011 - 2018, Lightbend, Inc.
|
||||
* Copyright 2008 - 2010, Mark Harrah
|
||||
* Licensed under Apache License 2.0 (see LICENSE)
|
||||
*/
|
||||
|
||||
package sbt.internal.util.appmacro
|
||||
|
||||
import scala.reflect.macros.blackbox
|
||||
|
||||
object StringTypeTag {
|
||||
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)"
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
* sbt
|
||||
* Copyright 2011 - 2018, Lightbend, Inc.
|
||||
* Copyright 2008 - 2010, Mark Harrah
|
||||
* Licensed under Apache License 2.0 (see LICENSE)
|
||||
*/
|
||||
|
||||
package sbt.internal.util.appmacro
|
||||
|
||||
final class StringTypeTag[A](val key: String):
|
||||
override def toString(): String = key
|
||||
override def equals(o: Any): Boolean = this.eq(o.asInstanceOf[AnyRef]) || (o match {
|
||||
case x: StringTypeTag[_] => (this.key == x.key)
|
||||
case _ => false
|
||||
})
|
||||
override def hashCode: Int = key.##
|
||||
end StringTypeTag
|
||||
|
||||
object StringTypeTag:
|
||||
inline given apply[A]: StringTypeTag[A] = ${ applyImpl[A] }
|
||||
|
||||
def manually[A](key: String): StringTypeTag[A] = new StringTypeTag(key)
|
||||
|
||||
import scala.quoted.*
|
||||
private def applyImpl[A: Type](using qctx: Quotes): Expr[StringTypeTag[A]] =
|
||||
import qctx.reflect._
|
||||
val tpe = TypeRepr.of[A]
|
||||
'{ new StringTypeTag[A](${ Expr(tpe.dealias.show) }) }
|
||||
end StringTypeTag
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
package sbt.internal
|
||||
|
||||
import sbt.internal.util.appmacro.*
|
||||
import verify.*
|
||||
|
||||
object StringTypeTagTest extends BasicTestSuite:
|
||||
test("String") {
|
||||
assert(StringTypeTag[String].toString == "java.lang.String")
|
||||
}
|
||||
|
||||
test("Int") {
|
||||
assert(StringTypeTag[Int].toString == "scala.Int")
|
||||
}
|
||||
|
||||
test("List[Int]") {
|
||||
assert(StringTypeTag[List[Int]].toString == "scala.collection.immutable.List[scala.Int]")
|
||||
}
|
||||
end StringTypeTagTest
|
||||
|
|
@ -1,57 +0,0 @@
|
|||
/*
|
||||
* sbt
|
||||
* Copyright 2011 - 2018, 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.runtime.universe._
|
||||
|
||||
/** 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 appmacro.StringTypeTag.impl[A]
|
||||
@deprecated("Prefer macro generated StringTypeTag", "1.4.0")
|
||||
def apply[A: TypeTag]: StringTypeTag[A] =
|
||||
synchronized {
|
||||
def doApply: StringTypeTag[A] = {
|
||||
val tag = implicitly[TypeTag[A]]
|
||||
val tpe = tag.tpe
|
||||
val k = typeToString(tpe)
|
||||
// println(tpe.getClass.toString + " " + k)
|
||||
StringTypeTag[A](k)
|
||||
}
|
||||
def retry(n: Int): StringTypeTag[A] =
|
||||
try {
|
||||
doApply
|
||||
} catch {
|
||||
case e: NullPointerException =>
|
||||
if (n < 1) throw new RuntimeException("NPE in StringTypeTag", e)
|
||||
else {
|
||||
Thread.sleep(1)
|
||||
retry(n - 1)
|
||||
}
|
||||
}
|
||||
retry(3)
|
||||
}
|
||||
|
||||
@deprecated("Prefer macro generated StringTypeTag", "1.4.0")
|
||||
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(",")}]"""
|
||||
} else tpe.toString
|
||||
case _ => tpe.toString
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue