diff options
author | Martin Odersky <odersky@gmail.com> | 2014-07-05 19:20:47 +0200 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2014-07-17 11:02:00 +0200 |
commit | 1fdc188af5b8b34b1a54555dc48e6f2ccb3294c8 (patch) | |
tree | a3b03731dbd176ababe950c42c769649c18932a3 /src/dotty/tools/dotc/transform/Literalize.scala | |
parent | 30013465f45b9085b044b7abec36d7bd8d3b1b2b (diff) | |
download | dotty-1fdc188af5b8b34b1a54555dc48e6f2ccb3294c8.tar.gz dotty-1fdc188af5b8b34b1a54555dc48e6f2ccb3294c8.tar.bz2 dotty-1fdc188af5b8b34b1a54555dc48e6f2ccb3294c8.zip |
New micro phase: Literalize
Convert expressions with constant types to Literals.
Diffstat (limited to 'src/dotty/tools/dotc/transform/Literalize.scala')
-rw-r--r-- | src/dotty/tools/dotc/transform/Literalize.scala | 65 |
1 files changed, 65 insertions, 0 deletions
diff --git a/src/dotty/tools/dotc/transform/Literalize.scala b/src/dotty/tools/dotc/transform/Literalize.scala new file mode 100644 index 000000000..14ce8fd05 --- /dev/null +++ b/src/dotty/tools/dotc/transform/Literalize.scala @@ -0,0 +1,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 TreeTransform { + import ast.tpd._ + + override def name: 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) +}
\ No newline at end of file |