1
1
package com .avsystem .commons
2
2
package misc
3
3
4
- import com .avsystem .commons .serialization .{GenCodec , GenKeyCodec , transparent }
4
+ import com .avsystem .commons .serialization .{GenCodec , GenKeyCodec }
5
5
6
6
/**
7
7
* 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}
22
22
* }}}
23
23
* Then, `listTypeRepr[Int]` will produce a string `"List[Int]"`
24
24
*/
25
- @ transparent
26
- case class TypeString [T ](value : String ) extends AnyVal
25
+ class TypeString [T ](val value : String ) extends AnyVal
27
26
object 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
29
29
30
30
implicit def materialize [T ]: TypeString [T ] = macro macros.misc.MiscMacros .typeString[T ]
31
31
32
32
implicit val keyCodec : GenKeyCodec [TypeString [_]] =
33
- GenKeyCodec .create[TypeString [Any ]](TypeString (_), _.value). asInstanceOf [ GenKeyCodec [ TypeString [_]]]
33
+ GenKeyCodec .create[TypeString [_ ]](new TypeString (_), _.value)
34
34
35
35
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 ]
37
88
}
0 commit comments