11package com .avsystem .commons
22package misc
33
4- import com .avsystem .commons .serialization .{GenCodec , GenKeyCodec , transparent }
4+ import com .avsystem .commons .serialization .{GenCodec , GenKeyCodec }
55
66/**
77 * Typeclass that contains string representation of a concrete type. This representation should correctly parse
@@ -22,16 +22,67 @@ import com.avsystem.commons.serialization.{GenCodec, GenKeyCodec, transparent}
2222 * }}}
2323 * Then, `listTypeRepr[Int]` will produce a string `"List[Int]"`
2424 */
25- @ transparent
26- case class TypeString [T ](value : String ) extends AnyVal
25+ class TypeString [T ](val value : String ) extends AnyVal
2726object TypeString {
28- def of [T ](implicit ts : TypeString [T ]): String = ts.value
27+ def apply [T ](implicit ts : TypeString [T ]): TypeString [T ] = ts
28+ def of [T : TypeString ]: String = TypeString [T ].value
2929
3030 implicit def materialize [T ]: TypeString [T ] = macro macros.misc.MiscMacros .typeString[T ]
3131
3232 implicit val keyCodec : GenKeyCodec [TypeString [_]] =
33- GenKeyCodec .create[TypeString [Any ]](TypeString (_), _.value). asInstanceOf [ GenKeyCodec [ TypeString [_]]]
33+ GenKeyCodec .create[TypeString [_ ]](new TypeString (_), _.value)
3434
3535 implicit val codec : GenCodec [TypeString [_]] =
36- GenCodec .materialize[TypeString [Any ]].asInstanceOf [GenCodec [TypeString [_]]]
36+ GenCodec .create[TypeString [_]](i => new TypeString (i.readString()), (o, ts) => o.writeString(ts.value))
37+ }
38+
39+ /**
40+ * Typeclass that contains JVM fully qualified class name corresponding to given type.
41+ * This class name should resolve to runtime class of given type when passed to `java.lang.Class.forName`.
42+ *
43+ * `JavaClassName` can be used instead of `ClassTag` in ScalaJS when ScalaJS linker is configured to drop class names.
44+ * Also, unlike `ClassTag`, `JavaClassName` contains just a string so it can be easily serialized and deserialized.
45+ */
46+ class JavaClassName [T ](val value : String ) extends AnyVal
47+ object JavaClassName extends JavaClassNameLowPrio {
48+ def apply [T ](implicit ts : JavaClassName [T ]): JavaClassName [T ] = ts
49+ def of [T : JavaClassName ]: String = JavaClassName [T ].value
50+
51+ implicit val NothingClassName : JavaClassName [Nothing ] = new JavaClassName (" scala.runtime.Nothing$" )
52+ implicit val NothingArrayClassName : JavaClassName [Array [Nothing ]] = new JavaClassName (" [Lscala.runtime.Nothing$;" )
53+ implicit val UnitClassName : JavaClassName [Unit ] = new JavaClassName (" void" )
54+ implicit val BooleanClassName : JavaClassName [Boolean ] = new JavaClassName (" boolean" )
55+ implicit val ByteClassName : JavaClassName [Byte ] = new JavaClassName (" byte" )
56+ implicit val ShortClassName : JavaClassName [Short ] = new JavaClassName (" short" )
57+ implicit val IntClassName : JavaClassName [Int ] = new JavaClassName (" int" )
58+ implicit val LongClassName : JavaClassName [Long ] = new JavaClassName (" long" )
59+ implicit val FloatClassName : JavaClassName [Float ] = new JavaClassName (" float" )
60+ implicit val DoubleClassName : JavaClassName [Double ] = new JavaClassName (" double" )
61+ implicit val CharClassName : JavaClassName [Char ] = new JavaClassName (" char" )
62+
63+ implicit def arrayClassName [T : JavaClassName ]: JavaClassName [Array [T ]] = {
64+ val elementName = JavaClassName .of[T ] match {
65+ case " void" => " Lscala.runtime.BoxedUnit;"
66+ case " boolean" => " Z"
67+ case " byte" => " B"
68+ case " short" => " S"
69+ case " int" => " I"
70+ case " long" => " J"
71+ case " float" => " F"
72+ case " double" => " D"
73+ case " char" => " C"
74+ case arr if arr.startsWith(" [" ) => arr
75+ case n => s " L $n; "
76+ }
77+ new JavaClassName (" [" + elementName)
78+ }
79+
80+ implicit val keyCodec : GenKeyCodec [JavaClassName [_]] =
81+ GenKeyCodec .create[JavaClassName [_]](new JavaClassName (_), _.value)
82+
83+ implicit val codec : GenCodec [JavaClassName [_]] =
84+ GenCodec .create[JavaClassName [_]](i => new JavaClassName (i.readString()), (o, ts) => o.writeString(ts.value))
85+ }
86+ trait JavaClassNameLowPrio { this : JavaClassName .type =>
87+ implicit def materialize [T ]: JavaClassName [T ] = macro macros.misc.MiscMacros .javaClassName[T ]
3788}
0 commit comments