@@ -28,6 +28,12 @@ object BooleanMacro {
28
28
def isImplicitMethodType (tp : Type ): Boolean =
29
29
Type .IsMethodType .unapply(tp).flatMap(tp => if tp.isImplicit then Some (true ) else None ).nonEmpty
30
30
31
+ def isByNameMethodType (tp : Type ): Boolean = tp.widen match {
32
+ case Type .MethodType (_, Type .ByNameType (_) :: Nil , _) => true
33
+ case _ => false
34
+ }
35
+
36
+
31
37
condition.unseal.underlyingArgument match {
32
38
case Apply (sel @ Select (Apply (qual, lhs :: Nil ), op @ (" ===" | " !==" )), rhs :: Nil ) =>
33
39
let(lhs) { left =>
@@ -41,7 +47,24 @@ object BooleanMacro {
41
47
}
42
48
}
43
49
}.seal.cast[Bool ]
50
+
44
51
case Apply (sel @ Select (lhs, op), rhs :: Nil ) =>
52
+ def binaryDefault =
53
+ if (isByNameMethodType(sel.tpe)) defaultCase
54
+ else
55
+ let(lhs) { left =>
56
+ let(rhs) { right =>
57
+ val app = left.select(sel.symbol).appliedTo(right)
58
+ let(app) { result =>
59
+ val l = left.seal
60
+ val r = right.seal
61
+ val b = result.seal.cast[Boolean ]
62
+ val code = ' { Bool .binaryMacroBool($l, $ {op.toExpr}, $r, $b, $prettifier) }
63
+ code.unseal
64
+ }
65
+ }
66
+ }.seal.cast[Bool ]
67
+
45
68
op match {
46
69
case " ||" =>
47
70
val left = parse(lhs.seal.cast[Boolean ], prettifier)
@@ -59,25 +82,43 @@ object BooleanMacro {
59
82
val left = parse(lhs.seal.cast[Boolean ], prettifier)
60
83
val right = parse(rhs.seal.cast[Boolean ], prettifier)
61
84
' { $left & $right }
62
- case _ =>
63
- sel.tpe.widen match {
64
- case Type .MethodType (_, Type .ByNameType (_) :: Nil , _) =>
65
- defaultCase
66
- case _ =>
67
- let(lhs) { left =>
85
+ case " ==" =>
86
+ lhs match {
87
+ case Apply (sel @ Select (lhs0, op @ (" length" | " size" )), Nil ) =>
88
+ let(lhs0) { left =>
89
+ let(rhs) { right =>
90
+ val actual = left.select(sel.symbol).appliedToArgs(Nil )
91
+ let(actual) { result =>
92
+ val l = left.seal
93
+ val r = right.seal
94
+ val res = result.seal
95
+ val code = ' { Bool .lengthSizeMacroBool($l, $ {op.toExpr}, $res, $r, $prettifier) }
96
+ code.unseal
97
+ }
98
+ }
99
+ }.seal.cast[Bool ]
100
+
101
+ case sel @ Select (lhs0, op @ (" length" | " size" )) =>
102
+ let(lhs0) { left =>
68
103
let(rhs) { right =>
69
- val app = left.select(sel.symbol).appliedTo(right )
70
- let(app ) { result =>
104
+ val actual = left.select(sel.symbol)
105
+ let(actual ) { result =>
71
106
val l = left.seal
72
107
val r = right.seal
73
- val b = result.seal.cast[ Boolean ]
74
- val code = ' { Bool .binaryMacroBool ($l, $ {op.toExpr}, $r , $b , $prettifier) }
108
+ val res = result.seal
109
+ val code = ' { Bool .lengthSizeMacroBool ($l, $ {op.toExpr}, $res , $r , $prettifier) }
75
110
code.unseal
76
111
}
77
112
}
78
113
}.seal.cast[Bool ]
114
+
115
+ case _ =>
116
+ binaryDefault
79
117
}
118
+ case _ =>
119
+ binaryDefault
80
120
}
121
+
81
122
case Apply (f @ Apply (sel @ Select (Apply (qual, lhs :: Nil ), op @ (" ===" | " !==" )), rhs :: Nil ), implicits)
82
123
if isImplicitMethodType(f.tpe) =>
83
124
let(lhs) { left =>
@@ -92,6 +133,7 @@ object BooleanMacro {
92
133
}
93
134
}
94
135
}.seal.cast[Bool ]
136
+
95
137
case Apply (TypeApply (sel @ Select (lhs, op), targs), rhs :: Nil ) =>
96
138
let(lhs) { left =>
97
139
let(rhs) { right =>
@@ -106,11 +148,32 @@ object BooleanMacro {
106
148
}
107
149
}.seal.cast[Bool ]
108
150
151
+ case Apply (sel @ Select (lhs, op @ (" isEmpty" | " nonEmpty" )), Nil ) =>
152
+ let(lhs) { l =>
153
+ val res = l.select(sel.symbol).appliedToArgs(Nil ).seal.cast[Boolean ]
154
+ ' { Bool .unaryMacroBool($ {l.seal}, $ { op.toExpr }, $res, $prettifier) }.unseal
155
+ }.seal.cast[Bool ]
156
+
109
157
case Select (left, " unary_!" ) =>
110
158
val receiver = parse(left.seal.cast[Boolean ], prettifier)
111
159
' { ! ($receiver) }
160
+
161
+ case sel @ Select (left, op @ (" isEmpty" | " nonEmpty" )) =>
162
+ let(left) { l =>
163
+ val res = l.select(sel.symbol).seal.cast[Boolean ]
164
+ ' { Bool .unaryMacroBool($ {l.seal}, $ { op.toExpr }, $res, $prettifier) }.unseal
165
+ }.seal.cast[Bool ]
166
+
167
+ case TypeApply (sel @ Select (lhs, " isInstanceOf" ), targs) =>
168
+ let(lhs) { l =>
169
+ val res = l.select(sel.symbol).appliedToTypeTrees(targs).seal.cast[Boolean ]
170
+ val name = targs.head.tpe.show(the[Context ].withoutColors).toExpr
171
+ ' { Bool .isInstanceOfMacroBool($ {l.seal}, " isInstanceOf" , $name, $res, $prettifier) }.unseal
172
+ }.seal.cast[Bool ]
173
+
112
174
case Literal (_) =>
113
175
' { Bool .simpleMacroBool($condition, " " , $prettifier) }
176
+
114
177
case _ =>
115
178
defaultCase
116
179
}
0 commit comments