File tree Expand file tree Collapse file tree 3 files changed +60
-0
lines changed Expand file tree Collapse file tree 3 files changed +60
-0
lines changed Original file line number Diff line number Diff line change @@ -5,6 +5,7 @@ Contents:
5
5
6
6
Type-level helpers
7
7
- EnumerateSingletons - listing all objects extending a sealed trait
8
+ - Defaults - object giving names access to a class's default values
8
9
9
10
Collection extensions (org.cvogt.collection)
10
11
- distinctBy - remove duplicates by key
Original file line number Diff line number Diff line change
1
+ package org .cvogt .scala
2
+
3
+ import scala .reflect .macros .whitebox .Context
4
+ import scala .language .dynamics
5
+ import scala .language .experimental .macros
6
+ import macrocompat .bundle
7
+
8
+ object Defaults {
9
+ /** returns the given type's default values in an anonymous class instance */
10
+ def apply [T ]: Any = macro DefaultsMacros .apply[T ]
11
+ }
12
+
13
+ @ bundle
14
+ class DefaultsMacros ( val c : Context ) {
15
+ import c .universe ._
16
+ def apply [T : c.WeakTypeTag ] = {
17
+ val T = weakTypeOf[T ]
18
+ if ( ! isCaseClass( T ) )
19
+ c.error( c.enclosingPosition, s " not a case class: $T" )
20
+ val defs = caseClassFieldsTypes( T ).collect {
21
+ case ( name, tpe, Some ( default ) ) => q " def ${TermName ( name )}: $tpe = $default"
22
+ }
23
+ q " new{ .. $defs } "
24
+ }
25
+
26
+ private def isCaseClass ( tpe : Type ) = tpe.typeSymbol.isClass && tpe.typeSymbol.asClass.isCaseClass
27
+
28
+ private def caseClassFieldsTypes ( tpe : Type ): List [( String , Type , Option [Tree ] )] = {
29
+ tpe.companion.member( TermName ( " apply" ) ).asTerm.alternatives.find( _.isSynthetic ).get.asMethod.paramLists.flatten.zipWithIndex.map {
30
+ case ( field, i ) =>
31
+ (
32
+ field.name.toTermName.decodedName.toString,
33
+ field.infoIn( tpe ),
34
+ {
35
+ val method = TermName ( s " apply $$ default $$ ${i + 1 }" )
36
+ tpe.companion.member( method ) match {
37
+ case NoSymbol => None
38
+ case _ => Some ( q " ${tpe.typeSymbol.companion}. $method" )
39
+ }
40
+ }
41
+ )
42
+ }.toList
43
+ }
44
+ }
Original file line number Diff line number Diff line change
1
+ package org .cvogt .scala .test
2
+
3
+ import org .cvogt .scala .Defaults
4
+
5
+ import org .scalatest .FunSuite
6
+
7
+ case class Foo (i : Int = 5 , s : String )
8
+ class DefaultsTest extends FunSuite {
9
+ test( " case class" ) {
10
+ val d = Defaults [Foo ]
11
+
12
+ import scala .language .reflectiveCalls
13
+ assert( d.i === 5 )
14
+ }
15
+ }
You can’t perform that action at this time.
0 commit comments