From ef118b8c86944d6fe3520782335835b9ec96590a Mon Sep 17 00:00:00 2001 From: Denys Shabalin Date: Wed, 22 Jan 2014 17:49:26 +0100 Subject: Tag synthetic unit with attachment This makes it easy to differentiate unit inserted by a compiler vs unit written by the user. Useful for quasiquotes and pretty printing. Additionally SyntacticBlock extractor is changed to treat EmptyTree as zero-element block. --- src/compiler/scala/tools/reflect/quasiquotes/Reifiers.scala | 4 ++-- src/reflect/scala/reflect/internal/BuildUtils.scala | 2 ++ src/reflect/scala/reflect/internal/StdAttachments.scala | 4 ++++ src/reflect/scala/reflect/internal/TreeGen.scala | 2 +- src/reflect/scala/reflect/runtime/JavaUniverseForce.scala | 1 + 5 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/compiler/scala/tools/reflect/quasiquotes/Reifiers.scala b/src/compiler/scala/tools/reflect/quasiquotes/Reifiers.scala index 87ab52414c..e0b863b749 100644 --- a/src/compiler/scala/tools/reflect/quasiquotes/Reifiers.scala +++ b/src/compiler/scala/tools/reflect/quasiquotes/Reifiers.scala @@ -189,8 +189,8 @@ trait Reifiers { self: Quasiquotes => mirrorBuildCall(nme.SyntacticBlock, tree) case Block(Nil, other) => reifyTree(other) - case Block(stats, last) => - reifyBuildCall(nme.SyntacticBlock, stats :+ last) + case SyntacticBlock(stats) if stats.size > 1 => + reifyBuildCall(nme.SyntacticBlock, stats) case Try(block, catches, finalizer) => reifyBuildCall(nme.SyntacticTry, block, catches, finalizer) case Match(selector, cases) => diff --git a/src/reflect/scala/reflect/internal/BuildUtils.scala b/src/reflect/scala/reflect/internal/BuildUtils.scala index 9b19dc11cb..fda8e4be5f 100644 --- a/src/reflect/scala/reflect/internal/BuildUtils.scala +++ b/src/reflect/scala/reflect/internal/BuildUtils.scala @@ -385,6 +385,8 @@ trait BuildUtils { self: SymbolTable => def apply(stats: List[Tree]): Tree = gen.mkBlock(stats) def unapply(tree: Tree): Option[List[Tree]] = tree match { + case EmptyTree => Some(Nil) + case self.Block(stats, expr) if expr.hasAttachment[SyntheticUnitAttachment.type] => Some(stats) case self.Block(stats, expr) => Some(stats :+ expr) case _ if tree.isTerm => Some(tree :: Nil) case _ => None diff --git a/src/reflect/scala/reflect/internal/StdAttachments.scala b/src/reflect/scala/reflect/internal/StdAttachments.scala index 09fd996f39..b331bf75f6 100644 --- a/src/reflect/scala/reflect/internal/StdAttachments.scala +++ b/src/reflect/scala/reflect/internal/StdAttachments.scala @@ -36,6 +36,10 @@ trait StdAttachments { */ case object ForAttachment extends PlainAttachment + /** Identifies unit constants which were inserted by the compiler. + */ + case object SyntheticUnitAttachment extends PlainAttachment + /** Untyped list of subpatterns attached to selector dummy. */ case class SubpatternsAttachment(patterns: List[Tree]) } diff --git a/src/reflect/scala/reflect/internal/TreeGen.scala b/src/reflect/scala/reflect/internal/TreeGen.scala index b16cbd8325..0e1eb7d3a9 100644 --- a/src/reflect/scala/reflect/internal/TreeGen.scala +++ b/src/reflect/scala/reflect/internal/TreeGen.scala @@ -447,7 +447,7 @@ abstract class TreeGen extends macros.TreeBuilder { /** Create block of statements `stats` */ def mkBlock(stats: List[Tree]): Tree = if (stats.isEmpty) Literal(Constant(())) - else if (!stats.last.isTerm) Block(stats, Literal(Constant(()))) + else if (!stats.last.isTerm) Block(stats, Literal(Constant(())).updateAttachment(SyntheticUnitAttachment)) else if (stats.length == 1) stats.head else Block(stats.init, stats.last) diff --git a/src/reflect/scala/reflect/runtime/JavaUniverseForce.scala b/src/reflect/scala/reflect/runtime/JavaUniverseForce.scala index b9b171c7ed..8811b5513e 100644 --- a/src/reflect/scala/reflect/runtime/JavaUniverseForce.scala +++ b/src/reflect/scala/reflect/runtime/JavaUniverseForce.scala @@ -58,6 +58,7 @@ trait JavaUniverseForce { self: runtime.JavaUniverse => this.CompoundTypeTreeOriginalAttachment this.BackquotedIdentifierAttachment this.ForAttachment + this.SyntheticUnitAttachment this.SubpatternsAttachment this.noPrint this.typeDebug -- cgit v1.2.3