diff options
author | Paul Phillips <paulp@improving.org> | 2012-09-12 19:32:28 -0700 |
---|---|---|
committer | Paul Phillips <paulp@improving.org> | 2012-09-12 20:47:39 -0700 |
commit | 5f674e44c5d3dccb55ce080c60d92b8e412d03ac (patch) | |
tree | 64362883bda37fa6beb7687364515363f31721a0 | |
parent | 1806830ec802feea0b89f1a71e0dc15c1507b965 (diff) | |
download | scala-5f674e44c5d3dccb55ce080c60d92b8e412d03ac.tar.gz scala-5f674e44c5d3dccb55ce080c60d92b8e412d03ac.tar.bz2 scala-5f674e44c5d3dccb55ce080c60d92b8e412d03ac.zip |
Rescued TreeBuilder from the parser.
For too long, Tree Builder has ruled over those who would
like to build their own trees. Today marks the start of a
new era. Trees are for building, not for parsers to hoard.
It's in Global now.
The particular motivation is exposing makeNew, and I also
added makeAnonymousNew, so rather than this...
Apply(Select(
Block(List(ClassDef(
Modifiers(scala.tools.nsc.symtab.Flags.FINAL), tpnme.ANON_CLASS_NAME, Nil,
Template(List(Ident(definitions.AnyRefClass)), emptyValDef, List(
DefDef(NoMods, nme.CONSTRUCTOR, Nil, List(Nil), TypeTree(), Block(
List(Apply(Select(Super(This(tpnme.EMPTY), tpnme.EMPTY), nme.CONSTRUCTOR), Nil)),
Literal(Constant(()))
)))))),
Apply(Select(New(Ident(tpnme.ANON_CLASS_NAME)), nme.CONSTRUCTOR), Nil))
, sn.GetClass), Nil)
We can write this.
Apply(Select(makeAnonymousNew(Nil), nme.getClass_), Nil)
-rw-r--r-- | src/compiler/scala/tools/nsc/Global.scala | 14 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/ast/parser/Parsers.scala | 13 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala | 9 |
3 files changed, 24 insertions, 12 deletions
diff --git a/src/compiler/scala/tools/nsc/Global.scala b/src/compiler/scala/tools/nsc/Global.scala index d101337087..9e3f47e8fb 100644 --- a/src/compiler/scala/tools/nsc/Global.scala +++ b/src/compiler/scala/tools/nsc/Global.scala @@ -13,7 +13,7 @@ import scala.collection.{ mutable, immutable } import io.{ SourceReader, AbstractFile, Path } import reporters.{ Reporter, ConsoleReporter } import util.{ Exceptional, ClassPath, MergedClassPath, StatisticsInfo, ScalaClassLoader, returning } -import scala.reflect.internal.util.{ NoPosition, SourceFile, NoSourceFile, BatchSourceFile, ScriptSourceFile } +import scala.reflect.internal.util.{ NoPosition, OffsetPosition, SourceFile, NoSourceFile, BatchSourceFile, ScriptSourceFile } import scala.reflect.internal.pickling.{ PickleBuffer, PickleFormat } import settings.{ AestheticSettings } import symtab.{ Flags, SymbolTable, SymbolLoaders, SymbolTrackers } @@ -96,6 +96,7 @@ class Global(var currentSettings: Settings, var reporter: Reporter) /** Generate ASTs */ type TreeGen = scala.tools.nsc.ast.TreeGen + /** Tree generation, usually based on existing symbols. */ override object gen extends { val global: Global.this.type = Global.this } with TreeGen { @@ -103,6 +104,17 @@ 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/parser/Parsers.scala b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala index e79c92e162..c925669444 100644 --- a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala +++ b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala @@ -280,14 +280,6 @@ self => /** whether a non-continuable syntax error has been seen */ private var lastErrorOffset : Int = -1 - object treeBuilder extends TreeBuilder { - val global: self.global.type = self.global - def freshName(prefix: String): Name = freshTermName(prefix) - def freshTermName(prefix: String): TermName = Parser.this.freshTermName(prefix) - def freshTypeName(prefix: String): TypeName = Parser.this.freshTypeName(prefix) - def o2p(offset: Int) = Parser.this.o2p(offset) - def r2p(start: Int, point: Int, end: Int) = Parser.this.r2p(start, point, end) - } import treeBuilder.{global => _, _} /** The types of the context bounds of type parameters of the surrounding class @@ -404,8 +396,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 mainNew = makeNew(Nil, emptyValDef, stmts, ListOfNil, NoPosition, NoPosition) - def mainDef = DefDef(NoMods, nme.main, Nil, List(mainParameter), scalaDot(tpnme.Unit), Block(mainSetArgv, mainNew)) + def mainDef = DefDef(NoMods, nme.main, Nil, List(mainParameter), scalaDot(tpnme.Unit), Block(mainSetArgv, makeAnonymousNew(stmts))) // object Main def moduleName = newTermName(ScriptRunner scriptMain settings) @@ -1302,7 +1293,7 @@ self => placeholderParams = placeholderParams ::: savedPlaceholderParams res } - + def expr0(location: Int): Tree = (in.token: @scala.annotation.switch) match { case IF => diff --git a/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala b/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala index edf747486a..afafff4a64 100644 --- a/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala +++ b/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala @@ -199,6 +199,15 @@ 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, ListOfNil, NoPosition, NoPosition) + } + /** Create positioned tree representing an object creation <new parents { stats } * @param npos the position of the new * @param cpos the position of the anonymous class starting with parents |