summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2012-09-12 19:32:28 -0700
committerPaul Phillips <paulp@improving.org>2012-09-12 20:47:39 -0700
commit5f674e44c5d3dccb55ce080c60d92b8e412d03ac (patch)
tree64362883bda37fa6beb7687364515363f31721a0 /src
parent1806830ec802feea0b89f1a71e0dc15c1507b965 (diff)
downloadscala-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)
Diffstat (limited to 'src')
-rw-r--r--src/compiler/scala/tools/nsc/Global.scala14
-rw-r--r--src/compiler/scala/tools/nsc/ast/parser/Parsers.scala13
-rw-r--r--src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala9
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