@@ -21,18 +21,19 @@ import Simplify.desugarIdent
21
21
* out (nested) if with equivalent branches wrt to isSimilar. For example:
22
22
* - if (b) exp else exp → b; exp
23
23
* - if (b1) e1 else if (b2) e1 else e2 → if (b1 || b2) e1 else e2
24
+ * - if(!b) e1 else e2 → if(b) e2 else e1
24
25
*
25
26
* - Constant propagation over pattern matching.
26
27
*
27
- * @author DarkDimius, OlivierBlanvillain
28
+ * @author DarkDimius, OlivierBlanvillain, gan74
28
29
*/
29
30
class ConstantFold (val simplifyPhase : Simplify ) extends Optimisation {
30
31
import ast .tpd ._
31
32
32
33
def visitor (implicit ctx : Context ) = NoVisitor
33
34
def clear (): Unit = ()
34
35
35
- def transformer (implicit ctx : Context ): Tree => Tree = { x => preEval(x) match {
36
+ def transformer (implicit ctx : Context ): Tree => Tree = { x => x match {
36
37
// TODO: include handling of isInstanceOf similar to one in IsInstanceOfEvaluator
37
38
// TODO: include methods such as Int.int2double(see ./tests/pos/harmonize.scala)
38
39
case If (cond1, thenp, elsep) if isSimilar(thenp, elsep) =>
@@ -76,9 +77,6 @@ import Simplify.desugarIdent
76
77
// cond.select(defn.Boolean_&&).appliedTo(elsep)
77
78
// the other case ins't handled intentionally. See previous case for explanation
78
79
79
- case If (t @ Select (recv, _), thenp, elsep) if t.symbol eq defn.Boolean_! =>
80
- If (recv, elsep, thenp)
81
-
82
80
case If (t @ Apply (Select (recv, _), Nil ), thenp, elsep) if t.symbol eq defn.Boolean_! =>
83
81
If (recv, elsep, thenp)
84
82
@@ -141,7 +139,16 @@ import Simplify.desugarIdent
141
139
// Block(List(lhs),
142
140
// ref(defn.throwMethod).appliedTo(New(defn.ArithmeticExceptionClass.typeRef, defn.ArithmeticExceptionClass_stringConstructor, Literal(Constant("/ by zero")) :: Nil)))
143
141
144
- case _ => t
142
+ case _ =>
143
+ val lhType = lhs.tpe.widenTermRefExpr
144
+ val rhType = rhs.tpe.widenTermRefExpr
145
+ (lhType, rhType) match {
146
+ case (ConstantType (_), ConstantType (_)) =>
147
+ val s = ConstFold .apply(t)
148
+ if ((s ne null ) && s.tpe.isInstanceOf [ConstantType ]) Literal (s.tpe.asInstanceOf [ConstantType ].value)
149
+ else t
150
+ case _ => t
151
+ }
145
152
}
146
153
147
154
// This case can only be triggered when running Simplify before pattern matching:
@@ -157,26 +164,11 @@ import Simplify.desugarIdent
157
164
158
165
case t : Literal => t
159
166
case t : CaseDef => t
160
- case t if ! isPureExpr(t) => t
161
- case t =>
162
- val s = ConstFold .apply(t)
163
- if ((s ne null ) && s.tpe.isInstanceOf [ConstantType ]) {
164
- val constant = s.tpe.asInstanceOf [ConstantType ].value
165
- Literal (constant)
166
- } else t
167
+ case t => t
167
168
}
168
169
}
169
170
170
- def preEval (t : Tree )(implicit ctx : Context ) = {
171
- if (t.isInstanceOf [Literal ] || t.isInstanceOf [CaseDef ] || ! isPureExpr(t)) t
172
- else {
173
- val s = ConstFold .apply(t)
174
- if ((s ne null ) && s.tpe.isInstanceOf [ConstantType ]) {
175
- val constant = s.tpe.asInstanceOf [ConstantType ].value
176
- Literal (constant)
177
- } else t
178
- }
179
- }
171
+
180
172
181
173
def isSimilar (t1 : Tree , t2 : Tree )(implicit ctx : Context ): Boolean = t1 match {
182
174
case t1 : Apply =>
0 commit comments