blob: 79f0dd493881f922ccefbd7a650975ed671d1173 (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
|
package dotty.tools.dotc
package transform
import TreeTransforms._
import core.DenotTransformers._
import core.Symbols._
import core.Contexts._
import core.Types._
import core.Flags._
import core.Decorators._
import core.StdNames.nme
import ast.Trees._
/** This phase rewrites idempotent expressions with constant types to Literals.
* The constant types are eliminated by erasure, so we need to keep
* the info about constantness in the trees.
*/
class Literalize extends MiniPhaseTransform {
import ast.tpd._
override def phaseName: String = "literalize"
/** Note: Demanding idempotency instead of purity is strictly speaking too loose.
* Example
*
* object O { final val x = 42; println("43") }
* O.x
*
* Strictly speaking we can't replace `O.x` with `42`. But this would make
* most expressions non-constant. Maybe we can change the spec to accept this
* kind of eliding behavior. Or else enforce true purity in the compiler.
* The choice will be affected by what we will do with `inline` and with
* Singleton type bounds (see SIP 23). Presumably
*
* object O1 { val x: Singleton = 42; println("43") }
* object O2 { inline val x = 42; println("43") }
*
* should behave differently.
*
* O1.x should have the same effect as { println("43"; 42 }
*
* whereas
*
* O2.x = 42
*
* Revisit this issue once we have implemented `inline`. Then we can demand
* purity of the prefix unless the selection goes to an inline val.
*/
def literalize(tree: Tree)(implicit ctx: Context): Tree = tree.tpe match {
case ConstantType(value) if isIdempotentExpr(tree) => Literal(value)
case _ => tree
}
override def transformIdent(tree: Ident)(implicit ctx: Context, info: TransformerInfo): Tree =
literalize(tree)
override def transformSelect(tree: Select)(implicit ctx: Context, info: TransformerInfo): Tree =
literalize(tree)
override def transformApply(tree: Apply)(implicit ctx: Context, info: TransformerInfo): Tree =
literalize(tree)
override def transformTypeApply(tree: TypeApply)(implicit ctx: Context, info: TransformerInfo): Tree =
literalize(tree)
}
|