Skip to content

Commit a2f58c5

Browse files
author
Oron Port
authored
Merge pull request #132 from soronpo/getarg_mods
Ovehauling the GetArg functionality
2 parents b4bbae4 + ad616c7 commit a2f58c5

File tree

11 files changed

+199
-166
lines changed

11 files changed

+199
-166
lines changed

src/main/scala/singleton/ops/impl/GeneralMacros.scala

Lines changed: 123 additions & 95 deletions
Large diffs are not rendered by default.
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
package singleton.ops.impl
2+
3+
4+
//This is just for testing the GetArg workaround a problem a string interpolator arguments are applied
5+
protected[singleton] object InterpolatorTest {
6+
trait Bar
7+
trait Tag[W] extends HasOut {
8+
type Out = W
9+
}
10+
type XBar[W] = Bar with Tag[W]
11+
12+
final implicit class InterpolatorSyntax(val sc: StringContext) {
13+
def bar(args: Bar*)(implicit interpolator : Interpolator[Bar]) : interpolator.Out = interpolator.value
14+
}
15+
trait Interpolator[T] extends HasOut {
16+
type Out <: T
17+
val value : Out
18+
}
19+
20+
object Interpolator {
21+
type Aux[T, Out0 <: T] = Interpolator[T]{type Out = Out0}
22+
implicit def ev[W] : Interpolator.Aux[Bar, XBar[W]] = macro Macro.interpolator
23+
}
24+
25+
protected object Macro {
26+
object whitebox { type Context = scala.reflect.macros.whitebox.Context }
27+
def interpolator(c: whitebox.Context) : c.Tree = {
28+
import c.universe._
29+
val widthTpe = c.internal.constantType(Constant(5))
30+
31+
q"""
32+
new singleton.ops.impl.InterpolatorTest.Interpolator[singleton.ops.impl.InterpolatorTest.Bar] {
33+
type Out = singleton.ops.impl.InterpolatorTest.XBar[$widthTpe]
34+
val value : Out = new singleton.ops.impl.InterpolatorTest.Bar{}.asInstanceOf[singleton.ops.impl.InterpolatorTest.XBar[$widthTpe]]
35+
}
36+
"""
37+
}
38+
}
39+
}

src/main/scala/singleton/ops/impl/Op.scala

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,11 @@ package singleton.ops.impl
22

33
import shapeless.Nat
44

5-
trait Op extends Serializable {
5+
trait HasOut extends Any with Serializable {
6+
type Out
7+
}
8+
9+
trait Op extends HasOut {
610
type OutWide
711
type Out
812
type OutNat <: Nat
@@ -23,9 +27,10 @@ protected[singleton] trait OpGen[O <: Op] {type Out; val value : Out}
2327
protected[singleton] object OpGen {
2428
type Aux[O <: Op, Ret_Out] = OpGen[O] {type Out = Ret_Out}
2529
implicit def impl[O <: Op](implicit o: O) : Aux[O, o.Out] = new OpGen[O] {type Out = o.Out; val value = o.value.asInstanceOf[o.Out]}
30+
implicit def getValue[O <: Op, Out](o : Aux[O, Out]) : Out = o.value
2631
}
2732

28-
trait OpCast[T, O <: Op] {type Out <: T; val value : Out}
33+
trait OpCast[T, O <: Op] extends HasOut {type Out <: T; val value : Out}
2934

3035

3136
@scala.annotation.implicitNotFound(msg = "Unable to prove type argument is a Nat.")

src/main/scala/singleton/ops/impl/OpId.scala

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ object OpId {
77
sealed trait Arg extends OpId //Argument
88
sealed trait AcceptNonLiteral extends OpId
99
sealed trait GetArg extends OpId
10-
sealed trait GetLHSArg extends OpId
1110
sealed trait ImplicitFound extends OpId
1211
sealed trait EnumCount extends OpId
1312
sealed trait ITE extends OpId //If-Then-Else

src/main/scala/singleton/ops/impl/OpMacros.scala

Lines changed: 0 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -86,53 +86,3 @@ object OpMacro {
8686
// (implicit op : OpMacro[N, S1, S2, S3]) : ValueOf[OpMacro[N, S1, S2, S3]] = new ValueOf(op)
8787
}
8888
/*******************************************************************************************************/
89-
90-
91-
/********************************************************************************************************
92-
* Get function/class argument's type
93-
*******************************************************************************************************/
94-
object GetArg {
95-
type Aux[ArgIdx, Out0] = GetArg[ArgIdx]{type Out = Out0}
96-
97-
@scala.annotation.implicitNotFound("Argument with index ${ArgIdx} not found")
98-
trait GetArg[ArgIdx] {
99-
type Out
100-
val value : Out
101-
}
102-
103-
object GetArg {
104-
implicit def call[ArgIdx, Out]: Aux[ArgIdx, Out] = macro Macro.impl[ArgIdx]
105-
106-
final class Macro(val c: whitebox.Context) extends GeneralMacros {
107-
def impl[ArgIdx : c.WeakTypeTag]: c.Tree =
108-
MaterializeGetArg(c.symbolOf[GetArg[_]], c.symbolOf[Aux[_,_]], c.weakTypeOf[ArgIdx], false)
109-
}
110-
implicit def toArgValue[I, Out](i : Aux[I, Out]) : Out = i.value
111-
}
112-
}
113-
/*******************************************************************************************************/
114-
115-
116-
/********************************************************************************************************
117-
* Get function/class argument's type
118-
*******************************************************************************************************/
119-
object GetLHSArg {
120-
type Aux[ArgIdx, Out0] = GetLHSArg[ArgIdx]{type Out = Out0}
121-
122-
@scala.annotation.implicitNotFound("Argument with index ${ArgIdx} not found")
123-
trait GetLHSArg[ArgIdx] {
124-
type Out
125-
val value : Out
126-
}
127-
128-
object GetLHSArg {
129-
implicit def call[ArgIdx, Out]: Aux[ArgIdx, Out] = macro Macro.impl[ArgIdx]
130-
131-
final class Macro(val c: whitebox.Context) extends GeneralMacros {
132-
def impl[ArgIdx : c.WeakTypeTag]: c.Tree =
133-
MaterializeGetArg(c.symbolOf[GetLHSArg[_]], c.symbolOf[Aux[_,_]], c.weakTypeOf[ArgIdx], true)
134-
}
135-
implicit def toArgValue[I, Out](i : Aux[I, Out]) : Out = i.value
136-
}
137-
}
138-
/*******************************************************************************************************/

src/main/scala/singleton/ops/package.scala

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -72,14 +72,24 @@ package object ops {
7272
protected[singleton] type Arg[Num, T, TWide] = OpMacro[OpId.Arg, Num, T, TWide] //Argument for real-time function creation
7373
protected[singleton] type GetType[Sym] = OpMacro[OpId.GetType, Sym, NP, NP] //Argument for real-time function creation
7474
type AcceptNonLiteral[P1] = OpMacro[OpId.AcceptNonLiteral, P1, NP, NP]
75-
type GetArg[ArgIdx] = OpMacro[OpId.GetArg, ArgIdx, NP, NP] //Use to get argument type of class/definition
76-
type GetLHSArg[ArgIdx] = OpMacro[OpId.GetLHSArg, ArgIdx, NP, NP] //Use to get argument type of the left-hand-side
75+
type GetArg[ArgIdx] = OpMacro[OpId.GetArg, ArgIdx, False, NP] //Use to get argument type of class/definition
76+
type GetLHSArg[ArgIdx] = OpMacro[OpId.GetArg, ArgIdx, True, NP] //Use to get argument type of the left-hand-side
7777
type ImplicitFound[Sym] = OpMacro[OpId.ImplicitFound, GetType[Sym], NP, NP] //Implicit Found boolean indication
7878
type EnumCount[Sym] = OpMacro[OpId.EnumCount, GetType[Sym], NP, NP] //Number of direct subclasses
79-
final val GetArg = impl.GetArg
80-
final val GetLHSArg = impl.GetLHSArg
79+
object GetArg {
80+
type Aux[ArgIdx, Out] = OpAuxGen[GetArg[ArgIdx], Out]
81+
}
82+
object GetLHSArg {
83+
type Aux[ArgIdx, Out] = OpAuxGen[GetLHSArg[ArgIdx], Out]
84+
}
8185
type GetArg0 = GetArg[W.`0`.T]
86+
object GetArg0 {
87+
type Aux[Out] = OpAuxGen[GetArg0, Out]
88+
}
8289
type GetLHSArg0 = GetLHSArg[W.`0`.T]
90+
object GetLHSArg0 {
91+
type Aux[Out] = OpAuxGen[GetLHSArg0, Out]
92+
}
8393
type Id[P1] = OpMacro[OpId.Id, P1, NP, NP]
8494
type ![P1] = OpMacro[OpId.!, P1, NP, NP]
8595
type Require[Cond] = OpMacro[OpId.Require, Cond, DefaultRequireMsg, NoSym]

src/main/scala/singleton/twoface/impl/CaseClassSkipper.scala

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,10 @@
11
package singleton.twoface.impl
22

3+
import singleton.ops.impl.HasOut
34
import singleton.twoface.TwoFace
45

56
import scala.reflect.macros.whitebox
67

7-
trait HasOut {
8-
type Out
9-
}
10-
118
sealed trait CaseClassSkipper[T <: HasOut] extends HasOut {
129
type Out
1310
def apply(value : T => Any, fallBack : => Boolean) : Out

src/main/scala/singleton/twoface/impl/TwoFaceShell.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
package singleton.twoface.impl
22
import singleton.twoface.TwoFace
33

4-
import singleton.ops.impl.GeneralMacros
4+
import singleton.ops.impl.{GeneralMacros, HasOut}
55
import scala.reflect.macros.whitebox
66

77
////////////////////////////////////////////////////////////////////////////////

src/main/scala_2.13+/singleton/twoface/impl/TwoFaceAny.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
package singleton.twoface.impl
22

33
import singleton.ops._
4-
import singleton.ops.impl.std
4+
import singleton.ops.impl.{std, HasOut}
55

6-
trait TwoFaceAny[Face, T] extends Any {
6+
trait TwoFaceAny[Face, T] extends Any with HasOut {
77
type Out = T
88
def isLiteral(implicit rt : RunTime[T]) : std.Boolean = !rt
99
@inline def getValue : Face

src/main/scala_2.13-/singleton/twoface/impl/TwoFaceAny.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
package singleton.twoface.impl
22

33
import singleton.ops._
4-
import singleton.ops.impl.{GeneralMacros, std}
4+
import singleton.ops.impl.{GeneralMacros, std, HasOut}
55

66
import scala.reflect.macros.whitebox
77

8-
trait TwoFaceAny[Face, T] extends Any {
8+
trait TwoFaceAny[Face, T] extends Any with HasOut {
99
type Out = T
1010
def isLiteral(implicit rt : RunTime[T]) : std.Boolean = !rt
1111
@inline def getValue : Face

0 commit comments

Comments
 (0)