diff options
author | Martin Odersky <odersky@gmail.com> | 2012-01-02 19:10:41 +0100 |
---|---|---|
committer | Paul Phillips <paulp@improving.org> | 2012-01-02 13:49:28 -0800 |
commit | beb875187914b12b1b9dbb5621447067e2926c7c (patch) | |
tree | 0021b5e8da609e8a9a18b191aec925b8835c8bf4 /src/compiler/scala/tools/nsc/ast/Trees.scala | |
parent | 3ad66eb5a3335b29c9d5e56b17155e030aeb7243 (diff) | |
download | scala-beb875187914b12b1b9dbb5621447067e2926c7c.tar.gz scala-beb875187914b12b1b9dbb5621447067e2926c7c.tar.bz2 scala-beb875187914b12b1b9dbb5621447067e2926c7c.zip |
Changed boxing of free mutable variables to be flexible wrt when liftcode takes place.
A major redesign that unifies the various different approaches to boxing of free variables. Free variables are marked with CAPTURED and eliminated by LambdaLift. I also added some hooks in MacroContext that a reifier needs to use.
Diffstat (limited to 'src/compiler/scala/tools/nsc/ast/Trees.scala')
-rw-r--r-- | src/compiler/scala/tools/nsc/ast/Trees.scala | 22 |
1 files changed, 22 insertions, 0 deletions
diff --git a/src/compiler/scala/tools/nsc/ast/Trees.scala b/src/compiler/scala/tools/nsc/ast/Trees.scala index 30ee7fc885..88a9b5e18b 100644 --- a/src/compiler/scala/tools/nsc/ast/Trees.scala +++ b/src/compiler/scala/tools/nsc/ast/Trees.scala @@ -44,6 +44,15 @@ trait Trees extends reflect.internal.Trees { self: Global => /** emitted by typer, eliminated by refchecks */ case class TypeTreeWithDeferredRefCheck()(val check: () => TypeTree) extends TypTree + + /** Marks underlying reference to id as boxed. + * @pre: id must refer to a captured variable + * A reference such marked will refer to the boxed entity, no dereferencing + * with `.elem` is done on it. + * This tree node can be emitted by macros such as reify that call markBoxedReference. + * It is eliminated in LambdaLift, where the boxing conversion takes place. + */ + case class ReferenceToBoxed(idt: Ident) extends TermTree // --- factory methods ---------------------------------------------------------- @@ -152,6 +161,8 @@ trait Trees extends reflect.internal.Trees { self: Global => traverser.traverse(lhs); traverser.traverse(rhs) case SelectFromArray(qualifier, selector, erasure) => traverser.traverse(qualifier) + case ReferenceToBoxed(idt) => + traverser.traverse(idt) case TypeTreeWithDeferredRefCheck() => // TODO: should we traverse the wrapped tree? // (and rewrap the result? how to update the deferred check? would need to store wrapped tree instead of returning it from check) case _ => super.xtraverse(traverser, tree) @@ -161,6 +172,7 @@ trait Trees extends reflect.internal.Trees { self: Global => def DocDef(tree: Tree, comment: DocComment, definition: Tree): DocDef def AssignOrNamedArg(tree: Tree, lhs: Tree, rhs: Tree): AssignOrNamedArg def SelectFromArray(tree: Tree, qualifier: Tree, selector: Name, erasure: Type): SelectFromArray + def ReferenceToBoxed(tree: Tree, idt: Ident): ReferenceToBoxed def TypeTreeWithDeferredRefCheck(tree: Tree): TypeTreeWithDeferredRefCheck } @@ -174,6 +186,8 @@ trait Trees extends reflect.internal.Trees { self: Global => new AssignOrNamedArg(lhs, rhs).copyAttrs(tree) def SelectFromArray(tree: Tree, qualifier: Tree, selector: Name, erasure: Type) = new SelectFromArray(qualifier, selector, erasure).copyAttrs(tree) + def ReferenceToBoxed(tree: Tree, idt: Ident) = + new ReferenceToBoxed(idt).copyAttrs(tree) def TypeTreeWithDeferredRefCheck(tree: Tree) = tree match { case dc@TypeTreeWithDeferredRefCheck() => new TypeTreeWithDeferredRefCheck()(dc.check).copyAttrs(tree) } @@ -195,6 +209,11 @@ trait Trees extends reflect.internal.Trees { self: Global => if (qualifier0 == qualifier) && (selector0 == selector) => t case _ => this.treeCopy.SelectFromArray(tree, qualifier, selector, erasure) } + def ReferenceToBoxed(tree: Tree, idt: Ident) = tree match { + case t @ ReferenceToBoxed(idt0) + if (idt0 == idt) => t + case _ => this.treeCopy.ReferenceToBoxed(tree, idt) + } def TypeTreeWithDeferredRefCheck(tree: Tree) = tree match { case t @ TypeTreeWithDeferredRefCheck() => t case _ => this.treeCopy.TypeTreeWithDeferredRefCheck(tree) @@ -220,6 +239,9 @@ trait Trees extends reflect.internal.Trees { self: Global => case SelectFromArray(qualifier, selector, erasure) => transformer.treeCopy.SelectFromArray( tree, transformer.transform(qualifier), selector, erasure) + case ReferenceToBoxed(idt) => + transformer.treeCopy.ReferenceToBoxed( + tree, transformer.transform(idt) match { case idt1: Ident => idt1 }) case TypeTreeWithDeferredRefCheck() => transformer.treeCopy.TypeTreeWithDeferredRefCheck(tree) } |