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