From 310df92551c33ed0242e9a50606732a9b02bfee8 Mon Sep 17 00:00:00 2001 From: Den Shabalin Date: Mon, 8 Jul 2013 20:24:45 +0200 Subject: moves TreeBuilder into the parser This is the first of the two patches to the parser necessary for quasiquotes to function. This one moves TreeBuilder from Global to the internals of the Parsers, so that quasiquotes will be able to override it later to support some corner cases arising from splicing (see the subsequent quasiquote commit for more details). Surprisingly enough, almost noone used TreeBuilder outside the parser, and it was necessary to move just a couple of methods to TreeGen to satisfy broken dependencies. --- src/compiler/scala/reflect/reify/package.scala | 2 +- src/compiler/scala/tools/nsc/Global.scala | 11 ----- src/compiler/scala/tools/nsc/ast/TreeGen.scala | 48 +++++++++++++++++++++ .../scala/tools/nsc/ast/parser/Parsers.scala | 18 ++++++-- .../scala/tools/nsc/ast/parser/TreeBuilder.scala | 49 +--------------------- 5 files changed, 64 insertions(+), 64 deletions(-) diff --git a/src/compiler/scala/reflect/reify/package.scala b/src/compiler/scala/reflect/reify/package.scala index d3cae3d123..30cfec8e2a 100644 --- a/src/compiler/scala/reflect/reify/package.scala +++ b/src/compiler/scala/reflect/reify/package.scala @@ -32,7 +32,7 @@ package object reify { // If we're in the constructor of an object or others don't have easy access to `this`, we have no good way to grab // the class of that object. Instead, we construct an anonymous class and grab his class file, assuming // this is enough to get the correct class loadeer for the class we *want* a mirror for, the object itself. - rClassTree orElse Apply(Select(treeBuilder.makeAnonymousNew(Nil), sn.GetClass), Nil) + rClassTree orElse Apply(Select(gen.mkAnonymousNew(Nil), sn.GetClass), Nil) } // JavaUniverse is defined in scala-reflect.jar, so we must be very careful in case someone reifies stuff having only scala-library.jar on the classpath val isJavaUniverse = JavaUniverseClass != NoSymbol && universe.tpe <:< JavaUniverseClass.toTypeConstructor diff --git a/src/compiler/scala/tools/nsc/Global.scala b/src/compiler/scala/tools/nsc/Global.scala index 603f9af1b4..ed97f78032 100644 --- a/src/compiler/scala/tools/nsc/Global.scala +++ b/src/compiler/scala/tools/nsc/Global.scala @@ -103,17 +103,6 @@ class Global(var currentSettings: Settings, var reporter: Reporter) typer.typed(mkCast(tree, pt)) } - /** Trees fresh from the oven, mostly for use by the parser. */ - object treeBuilder extends { - val global: Global.this.type = Global.this - } with TreeBuilder { - def freshName(prefix: String): Name = freshTermName(prefix) - def freshTermName(prefix: String): TermName = currentUnit.freshTermName(prefix) - def freshTypeName(prefix: String): TypeName = currentUnit.freshTypeName(prefix) - def o2p(offset: Int): Position = new OffsetPosition(currentUnit.source, offset) - def r2p(start: Int, mid: Int, end: Int): Position = rangePos(currentUnit.source, start, mid, end) - } - /** Fold constants */ object constfold extends { val global: Global.this.type = Global.this diff --git a/src/compiler/scala/tools/nsc/ast/TreeGen.scala b/src/compiler/scala/tools/nsc/ast/TreeGen.scala index c28a6ba337..d60daaa2bc 100644 --- a/src/compiler/scala/tools/nsc/ast/TreeGen.scala +++ b/src/compiler/scala/tools/nsc/ast/TreeGen.scala @@ -255,4 +255,52 @@ abstract class TreeGen extends scala.reflect.internal.TreeGen with TreeDSL { attrThis, If(cond, Block(syncBody: _*), EmptyTree)) :: stats: _*) + + /** Creates a tree representing new Object { stats }. + * To make sure an anonymous subclass of Object is created, + * if there are no stats, a () is added. + */ + def mkAnonymousNew(stats: List[Tree]): Tree = { + val stats1 = if (stats.isEmpty) List(Literal(Constant(()))) else stats + mkNew(Nil, emptyValDef, stats1, NoPosition, NoPosition) + } + + /** Create positioned tree representing an object creation val global : Global import global._ def newLiteral(const: Any) = Literal(Constant(const)) def literalUnit = newLiteral(()) + class ParserTreeBuilder extends TreeBuilder { + val global: self.global.type = self.global + def freshName(prefix: String): Name = freshTermName(prefix) + def freshTermName(prefix: String): TermName = currentUnit.freshTermName(prefix) + def freshTypeName(prefix: String): TypeName = currentUnit.freshTypeName(prefix) + def o2p(offset: Int): Position = new OffsetPosition(currentUnit.source, offset) + def r2p(start: Int, mid: Int, end: Int): Position = rangePos(currentUnit.source, start, mid, end) + } + /** This is now an abstract class, only to work around the optimizer: * methods in traits are never inlined. */ @@ -290,6 +299,7 @@ self => /** whether a non-continuable syntax error has been seen */ private var lastErrorOffset : Int = -1 + val treeBuilder = new ParserTreeBuilder import treeBuilder.{global => _, _} /** The types of the context bounds of type parameters of the surrounding class @@ -399,7 +409,7 @@ self => def mainParamType = AppliedTypeTree(Ident(tpnme.Array), List(Ident(tpnme.String))) def mainParameter = List(ValDef(Modifiers(Flags.PARAM), nme.argv, mainParamType, EmptyTree)) def mainSetArgv = List(ValDef(NoMods, nme.args, TypeTree(), Ident(nme.argv))) - def mainDef = DefDef(NoMods, nme.main, Nil, List(mainParameter), scalaDot(tpnme.Unit), Block(mainSetArgv, makeAnonymousNew(stmts))) + def mainDef = DefDef(NoMods, nme.main, Nil, List(mainParameter), scalaDot(tpnme.Unit), Block(mainSetArgv, gen.mkAnonymousNew(stmts))) // object Main def moduleName = newTermName(ScriptRunner scriptMain settings) @@ -1501,7 +1511,7 @@ self => val pname = freshName("x$") in.nextToken() val id = atPos(start) (Ident(pname)) - val param = atPos(id.pos.focus){ makeSyntheticParam(pname.toTermName) } + val param = atPos(id.pos.focus){ gen.mkSyntheticParam(pname.toTermName) } placeholderParams = param :: placeholderParams id case LPAREN => @@ -1516,7 +1526,7 @@ self => val tstart = in.offset val (parents, self, stats) = template() val cpos = r2p(tstart, tstart, in.lastOffset max tstart) - makeNew(parents, self, stats, npos, cpos) + gen.mkNew(parents, self, stats, npos, cpos) case _ => syntaxErrorOrIncompleteAnd("illegal start of simple expression", skipIt = true)(errorTermTree) } diff --git a/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala b/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala index 0ef71fa1b5..666f19851d 100644 --- a/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala +++ b/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala @@ -190,50 +190,6 @@ abstract class TreeBuilder { } } - /** Creates a tree representing new Object { stats }. - * To make sure an anonymous subclass of Object is created, - * if there are no stats, a () is added. - */ - def makeAnonymousNew(stats: List[Tree]): Tree = { - val stats1 = if (stats.isEmpty) List(Literal(Constant(()))) else stats - makeNew(Nil, emptyValDef, stats1, NoPosition, NoPosition) - } - - /** Create positioned tree representing an object creation */ def makeAssign(lhs: Tree, rhs: Tree): Tree = lhs match { case Apply(fn, args) => @@ -303,9 +259,6 @@ abstract class TreeBuilder { def makeParam(pname: TermName, tpe: Tree) = ValDef(Modifiers(PARAM), pname, tpe, EmptyTree) - def makeSyntheticParam(pname: TermName) = - ValDef(Modifiers(PARAM | SYNTHETIC), pname, TypeTree(), EmptyTree) - def makeSyntheticTypeParam(pname: TypeName, bounds: Tree) = TypeDef(Modifiers(DEFERRED | SYNTHETIC), pname, Nil, bounds) @@ -467,7 +420,7 @@ abstract class TreeBuilder { val x = freshTermName(prefix) val id = Ident(x) val sel = if (checkExhaustive) id else gen.mkUnchecked(id) - Function(List(makeSyntheticParam(x)), Match(sel, cases)) + Function(List(gen.mkSyntheticParam(x)), Match(sel, cases)) } /** Create tree for case definition rhs> */ -- cgit v1.2.3