summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xsrc/compiler/scala/reflect/api/AnnotationInfos.scala42
-rwxr-xr-xsrc/compiler/scala/reflect/api/Constants.scala43
-rw-r--r--src/compiler/scala/reflect/api/Modifier.scala11
-rwxr-xr-xsrc/compiler/scala/reflect/api/Names.scala30
-rw-r--r--src/compiler/scala/reflect/api/Positions.scala9
-rwxr-xr-xsrc/compiler/scala/reflect/api/Scopes.scala11
-rwxr-xr-xsrc/compiler/scala/reflect/api/StandardDefinitions.scala66
-rwxr-xr-xsrc/compiler/scala/reflect/api/Symbols.scala158
-rw-r--r--src/compiler/scala/reflect/api/Trees.scala1302
-rwxr-xr-xsrc/compiler/scala/reflect/api/Types.scala124
-rwxr-xr-xsrc/compiler/scala/reflect/api/Universe.scala16
-rw-r--r--src/compiler/scala/reflect/internal/AnnotationInfos.scala10
-rw-r--r--src/compiler/scala/reflect/internal/Constants.scala6
-rw-r--r--src/compiler/scala/reflect/internal/Definitions.scala4
-rw-r--r--src/compiler/scala/reflect/internal/Flags.scala31
-rw-r--r--src/compiler/scala/reflect/internal/Names.scala13
-rw-r--r--src/compiler/scala/reflect/internal/Positions.scala5
-rw-r--r--src/compiler/scala/reflect/internal/Scopes.scala2
-rw-r--r--src/compiler/scala/reflect/internal/SymbolTable.scala4
-rw-r--r--src/compiler/scala/reflect/internal/Symbols.scala13
-rw-r--r--src/compiler/scala/reflect/internal/TreeInfo.scala65
-rw-r--r--src/compiler/scala/reflect/internal/TreePrinters.scala21
-rw-r--r--src/compiler/scala/reflect/internal/Trees.scala1600
-rw-r--r--src/compiler/scala/reflect/internal/Types.scala38
-rw-r--r--src/compiler/scala/reflect/internal/pickling/UnPickler.scala18
-rw-r--r--src/compiler/scala/reflect/runtime/AbstractFile.scala5
-rw-r--r--src/compiler/scala/reflect/runtime/Universe.scala37
-rw-r--r--src/compiler/scala/tools/nsc/ast/TreeInfo.scala45
-rw-r--r--src/compiler/scala/tools/nsc/ast/TreePrinters.scala24
-rw-r--r--src/compiler/scala/tools/nsc/ast/Trees.scala282
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala2
-rw-r--r--src/continuations/plugin/scala/tools/selectivecps/SelectiveCPSTransform.scala2
32 files changed, 2429 insertions, 1610 deletions
diff --git a/src/compiler/scala/reflect/api/AnnotationInfos.scala b/src/compiler/scala/reflect/api/AnnotationInfos.scala
new file mode 100755
index 0000000000..96a65606e5
--- /dev/null
+++ b/src/compiler/scala/reflect/api/AnnotationInfos.scala
@@ -0,0 +1,42 @@
+package scala.reflect
+package api
+
+trait AnnotationInfos { self: Universe =>
+
+ type AnnotationInfo <: AnyRef
+ val AnnotationInfo: AnnotationInfoExtractor
+
+ abstract class AnnotationInfoExtractor {
+ def apply(atp: Type, args: List[Tree], assocs: List[(Name, ClassfileAnnotArg)]): AnnotationInfo
+ def unapply(info: AnnotationInfo): Option[(Type, List[Tree], List[(Name, ClassfileAnnotArg)])]
+ }
+
+ type ClassfileAnnotArg <: AnyRef
+ implicit def classfileAnnotArgManifest: ClassManifest[ClassfileAnnotArg] // need a precise manifest to pass to UnPickle's toArray call
+
+ type LiteralAnnotArg <: ClassfileAnnotArg
+ val LiteralAnnotArg: LiteralAnnotArgExtractor
+
+ type ArrayAnnotArg <: ClassfileAnnotArg
+ val ArrayAnnotArg: ArrayAnnotArgExtractor
+
+ type NestedAnnotArg <: ClassfileAnnotArg
+ val NestedAnnotArg: NestedAnnotArgExtractor
+
+ abstract class LiteralAnnotArgExtractor {
+ def apply(const: Constant): LiteralAnnotArg
+ def unapply(arg: LiteralAnnotArg): Option[Constant]
+ }
+
+ abstract class ArrayAnnotArgExtractor {
+ def apply(const: Array[ClassfileAnnotArg]): ArrayAnnotArg
+ def unapply(arg: ArrayAnnotArg): Option[Array[ClassfileAnnotArg]]
+ }
+
+ abstract class NestedAnnotArgExtractor {
+ def apply(anninfo: AnnotationInfo): NestedAnnotArg
+ def unapply(arg: NestedAnnotArg): Option[AnnotationInfo]
+ }
+}
+
+
diff --git a/src/compiler/scala/reflect/api/Constants.scala b/src/compiler/scala/reflect/api/Constants.scala
new file mode 100755
index 0000000000..42a0fa8a27
--- /dev/null
+++ b/src/compiler/scala/reflect/api/Constants.scala
@@ -0,0 +1,43 @@
+/* NSC -- new Scala compiler
+ * Copyright 2005-2011 LAMP/EPFL
+ * @author Martin Odersky
+ */
+
+package scala.reflect
+package api
+
+import java.lang.Integer.toOctalString
+import annotation.switch
+
+trait Constants {
+ self: Universe =>
+
+ abstract class AbsConstant {
+ val value: Any
+ def tpe: Type
+ def isNaN: Boolean
+
+ def booleanValue: Boolean
+ def byteValue: Byte
+ def shortValue: Short
+ def charValue: Char
+ def intValue: Int
+ def longValue: Long
+ def floatValue: Float
+ def doubleValue: Double
+ def stringValue: String
+ def typeValue: Type
+ def symbolValue: Symbol
+
+ def convertTo(pt: Type): Constant
+ }
+
+ type Constant <: AbsConstant
+
+ val Constant: ConstantExtractor
+
+ abstract class ConstantExtractor {
+ def apply(const: Any): Constant
+ def unapply(arg: Constant): Option[Any]
+ }
+}
diff --git a/src/compiler/scala/reflect/api/Modifier.scala b/src/compiler/scala/reflect/api/Modifier.scala
new file mode 100644
index 0000000000..5992e658c6
--- /dev/null
+++ b/src/compiler/scala/reflect/api/Modifier.scala
@@ -0,0 +1,11 @@
+package scala.reflect.api
+
+object Modifier extends Enumeration {
+
+ val `protected`, `private`, `override`, `abstract`, `final`,
+ `sealed`, `implicit`, `lazy`, `case`, `trait`,
+ deferred, interface, mutable, parameter, covariant, contravariant,
+ preSuper, abstractOverride, local, java, static, caseAccessor,
+ defaultParameter, defaultInit, paramAccessor, bynameParameter = Value
+
+} \ No newline at end of file
diff --git a/src/compiler/scala/reflect/api/Names.scala b/src/compiler/scala/reflect/api/Names.scala
new file mode 100755
index 0000000000..76e50497de
--- /dev/null
+++ b/src/compiler/scala/reflect/api/Names.scala
@@ -0,0 +1,30 @@
+package scala.reflect
+package api
+
+trait Names {
+
+ type Name >: Null <: AbsName
+ type TypeName <: Name
+ type TermName <: Name
+
+ abstract class AbsName {
+ def isTermName: Boolean
+ def isTypeName: Boolean
+ def toTermName: TermName
+ def toTypeName: TypeName
+ }
+
+ def newTermName(cs: Array[Char], offset: Int, len: Int): TermName
+ def newTermName(cs: Array[Byte], offset: Int, len: Int): TermName
+ def newTermName(s: String): TermName
+
+ def newTypeName(cs: Array[Char], offset: Int, len: Int): TypeName
+ def newTypeName(cs: Array[Byte], offset: Int, len: Int): TypeName
+ def newTypeName(s: String): TypeName
+
+ implicit def promoteTermNamesAsNecessary(name: Name): TermName = name.toTermName
+
+ def EmptyTermName: TermName = newTermName("")
+ def EmptyTypeName: TypeName = EmptyTermName.toTypeName
+}
+
diff --git a/src/compiler/scala/reflect/api/Positions.scala b/src/compiler/scala/reflect/api/Positions.scala
new file mode 100644
index 0000000000..181e7c1525
--- /dev/null
+++ b/src/compiler/scala/reflect/api/Positions.scala
@@ -0,0 +1,9 @@
+package scala.reflect
+package api
+
+trait Positions {
+
+ type Position
+ val NoPosition: Position
+
+} \ No newline at end of file
diff --git a/src/compiler/scala/reflect/api/Scopes.scala b/src/compiler/scala/reflect/api/Scopes.scala
new file mode 100755
index 0000000000..d4e4e24f29
--- /dev/null
+++ b/src/compiler/scala/reflect/api/Scopes.scala
@@ -0,0 +1,11 @@
+package scala.reflect
+package api
+
+trait Scopes { self: Universe =>
+
+ type Scope <: Iterable[Symbol]
+
+ def newScope(): Scope
+}
+
+
diff --git a/src/compiler/scala/reflect/api/StandardDefinitions.scala b/src/compiler/scala/reflect/api/StandardDefinitions.scala
new file mode 100755
index 0000000000..fd76245ea8
--- /dev/null
+++ b/src/compiler/scala/reflect/api/StandardDefinitions.scala
@@ -0,0 +1,66 @@
+/* NSC -- new Scala compiler
+ * Copyright 2005-2011 LAMP/EPFL
+ * @author Martin Odersky
+ */
+
+package scala.reflect
+package api
+
+trait StandardDefinitions { self: Universe =>
+
+ val definitions: AbsDefinitions
+
+ abstract class AbsDefinitions {
+
+ // outer packages and their classes
+ def RootPackage: Symbol
+ def RootClass: Symbol
+ def EmptyPackage: Symbol
+ def EmptyPackageClass: Symbol
+
+ def ScalaPackage: Symbol
+ def ScalaPackageClass: Symbol
+
+ // top types
+ def AnyClass : Symbol
+ def AnyValClass: Symbol
+ def AnyRefClass: Symbol
+ def ObjectClass: Symbol
+
+ // bottom types
+ def NullClass : Symbol
+ def NothingClass: Symbol
+
+ // the scala value classes
+ def UnitClass : Symbol
+ def ByteClass : Symbol
+ def ShortClass : Symbol
+ def CharClass : Symbol
+ def IntClass : Symbol
+ def LongClass : Symbol
+ def FloatClass : Symbol
+ def DoubleClass : Symbol
+ def BooleanClass: Symbol
+
+ // fundamental reference classes
+ def SymbolClass : Symbol
+ def StringClass : Symbol
+ def ClassClass : Symbol
+
+ // fundamental modules
+ def PredefModule: Symbol
+
+ // fundamental type constructions
+ def ClassType(arg: Type): Type
+
+ /** The string representation used by the given type in the VM.
+ */
+ def signature(tp: Type): String
+
+ /** Is symbol one of the value classes? */
+ def isValueClass(sym: Symbol): Boolean
+
+ /** Is symbol one of the numeric value classes? */
+ def isNumericValueClass(sym: Symbol): Boolean
+ }
+}
diff --git a/src/compiler/scala/reflect/api/Symbols.scala b/src/compiler/scala/reflect/api/Symbols.scala
new file mode 100755
index 0000000000..d13d0b40eb
--- /dev/null
+++ b/src/compiler/scala/reflect/api/Symbols.scala
@@ -0,0 +1,158 @@
+package scala.reflect
+package api
+
+trait Symbols { self: Universe =>
+
+ type Symbol >: Null <: AbsSymbol
+
+ abstract class AbsSymbol { this: Symbol =>
+
+ /** The modifiers of this symbol
+ */
+ def allModifiers: Set[Modifier.Value]
+
+ /** Does this symbol have given modifier?
+ */
+ def hasModifier(mod: Modifier.Value): Boolean
+
+ /** The owner of this symbol.
+ */
+ def owner: Symbol
+
+ /** The name of the symbol as a member of the `Name` type.
+ */
+ def name: Name
+
+ /** The name of the symbol before decoding, e.g. `\$eq\$eq` instead of `==`.
+ */
+ def encodedName: String
+
+ /** The decoded name of the symbol, e.g. `==` instead of `\$eq\$eq`.
+ */
+ def decodedName: String
+
+ /** The encoded full path name of this symbol, where outer names and inner names
+ * are separated by periods.
+ */
+ def fullName: String
+
+ /**
+ * Set when symbol has a modifier of the form private[X], NoSymbol otherwise.
+ *
+ * Access level encoding: there are three scala flags (PRIVATE, PROTECTED,
+ * and LOCAL) which combine with value privateWithin (the "foo" in private[foo])
+ * to define from where an entity can be accessed. The meanings are as follows:
+ *
+ * PRIVATE access restricted to class only.
+ * PROTECTED access restricted to class and subclasses only.
+ * LOCAL can only be set in conjunction with PRIVATE or PROTECTED.
+ * Further restricts access to the same object instance.
+ *
+ * In addition, privateWithin can be used to set a visibility barrier.
+ * When set, everything contained in the named enclosing package or class
+ * has access. It is incompatible with PRIVATE or LOCAL, but is additive
+ * with PROTECTED (i.e. if either the flags or privateWithin allow access,
+ * then it is allowed.)
+ *
+ * The java access levels translate as follows:
+ *
+ * java private: hasFlag(PRIVATE) && !hasAccessBoundary
+ * java package: !hasFlag(PRIVATE | PROTECTED) && (privateWithin == enclosing package)
+ * java protected: hasFlag(PROTECTED) && (privateWithin == enclosing package)
+ * java public: !hasFlag(PRIVATE | PROTECTED) && !hasAccessBoundary
+ */
+ def privateWithin: Symbol
+
+ /** Whether this symbol has a "privateWithin" visibility barrier attached.
+ */
+ def hasAccessBoundary: Boolean
+
+ /** A list of annotations attached to this Symbol.
+ */
+ def annotations: List[self.AnnotationInfo]
+
+ /** The type of the symbol
+ */
+ def tpe: Type
+
+ /** The info of the symbol. This is like tpe, except for class symbols where the `info`
+ * describes the contents of the class whereas the `tpe` is a reference to the class.
+ */
+ def info: Type
+
+ /** If this symbol is a class or trait, its self type, otherwise the type of the symbol itse;lf
+ */
+ def typeOfThis: Type
+
+ /** For a module class its linked class, for a plain class
+ * the module class of its linked module.
+ * For instance
+ * object Foo
+ * class Foo
+ *
+ * Then object Foo has a `moduleClass` (invisible to the user, the backend calls it Foo$
+ * linkedClassOfClass goes from class Foo$ to class Foo, and back.
+ */
+ def linkedClassOfClass: Symbol
+
+ /** The module corresponding to this module class (note that this
+ * is not updated when a module is cloned), or NoSymbol if this is not a ModuleClass
+ */
+ def sourceModule: Symbol
+
+ /** If symbol is an object definition, it's implied associated class,
+ * otherwise NoSymbol
+ */
+ def moduleClass: Symbol
+
+ /** The top-level class containing this symbol. */
+ def toplevelClass: Symbol
+
+ /**
+ * If symbol is a lazy val, it's lazy accessor
+ */
+ def lazyAccessor: Symbol
+
+ /** The next enclosing class */
+ def enclClass : Symbol
+
+ /** The next enclosing method */
+ def enclMethod : Symbol
+
+ def isTerm : Boolean
+ def isType : Boolean
+ def isClass : Boolean
+ def isAliasType : Boolean
+ def isAbstractType : Boolean
+
+ def isAbstractClass: Boolean
+ def isBridge : Boolean
+ def isContravariant: Boolean
+ def isCovariant : Boolean
+ def isEarlyInitialized : Boolean
+ def isExistentiallyBound: Boolean
+ def isImplClass : Boolean
+ def isLazyAccessor : Boolean
+ def isMethod : Boolean
+ def isVarargsMethod: Boolean
+ def isModule : Boolean
+ def isModuleClass : Boolean
+ def isOverloaded : Boolean
+ def isRefinementClass: Boolean
+ def isSourceMethod : Boolean
+ def isTypeParameter: Boolean
+
+ /** Package tests */
+ def isPackage : Boolean
+ def isPackageClass : Boolean
+ def isRootPackage : Boolean
+ def isRoot : Boolean
+ def isEmptyPackage : Boolean
+ def isEmptyPackageClass: Boolean
+
+ }
+
+ val NoSymbol: Symbol
+}
+
+
diff --git a/src/compiler/scala/reflect/api/Trees.scala b/src/compiler/scala/reflect/api/Trees.scala
new file mode 100644
index 0000000000..3374b38b51
--- /dev/null
+++ b/src/compiler/scala/reflect/api/Trees.scala
@@ -0,0 +1,1302 @@
+/* NSC -- new Scala compiler
+ * Copyright 2005-2011 LAMP/EPFL
+ * @author Martin Odersky
+ */
+
+package scala.reflect
+package api
+
+import java.io.{PrintWriter, StringWriter}
+import scala.collection.mutable.ListBuffer
+
+//import scala.tools.nsc.util.{ FreshNameCreator, HashSet, SourceFile }
+
+trait Trees /*extends reflect.generic.Trees*/ { self: Universe =>
+
+ private[scala] var nodeCount = 0
+
+ type Modifiers <: AbsModifiers
+
+ abstract class AbsModifiers {
+ def hasModifier(mod: Modifier.Value): Boolean
+ def allModifiers: Set[Modifier.Value]
+ def privateWithin: Name // default: EmptyTypeName
+ def annotations: List[Tree] // default: List()
+ def mapAnnotations(f: List[Tree] => List[Tree]): Modifiers
+ }
+
+ def Modifiers(mods: Set[Modifier.Value] = Set(),
+ privateWithin: Name = EmptyTypeName,
+ annotations: List[Tree] = List()): Modifiers
+
+ // ------ tree base classes --------------------------------------------------
+
+ /** The base class for all trees */
+ abstract class Tree extends Product {
+ val id = nodeCount
+ nodeCount += 1
+
+ private[this] var rawpos: Position = NoPosition
+
+ def pos = rawpos
+ def pos_=(pos: Position) = rawpos = pos
+ def setPos(pos: Position): this.type = { rawpos = pos; this }
+
+ private[this] var rawtpe: Type = _
+
+ def tpe = rawtpe
+ def tpe_=(t: Type) = rawtpe = t
+
+ /** Set tpe to give `tp` and return this.
+ */
+ def setType(tp: Type): this.type = { rawtpe = tp; this }
+
+ /** Like `setType`, but if this is a previously empty TypeTree
+ * that fact is remembered so that resetType will snap back.
+ */
+ def defineType(tp: Type): this.type = setType(tp)
+
+ def symbol: Symbol = null
+ def symbol_=(sym: Symbol) { throw new UnsupportedOperationException("symbol_= inapplicable for " + this) }
+ def setSymbol(sym: Symbol): this.type = { symbol = sym; this }
+
+ def hasSymbol = false
+ def isDef = false
+ def isEmpty = false
+
+ def hasSymbolWhich(f: Symbol => Boolean) = hasSymbol && f(symbol)
+
+ def isTerm: Boolean = this match {
+ case _: TermTree => true
+ case Bind(name, _) => name.isTermName
+ case Select(_, name) => name.isTermName
+ case Ident(name) => name.isTermName
+ case Annotated(_, arg) => arg.isTerm
+ case _ => false
+ }
+
+ def isType: Boolean = this match {
+ case _: TypTree => true
+ case Bind(name, _) => name.isTypeName
+ case Select(_, name) => name.isTypeName
+ case Ident(name) => name.isTypeName
+ case Annotated(_, arg) => arg.isType
+ case _ => false
+ }
+
+ /** Apply `f` to each subtree */
+ def foreach(f: Tree => Unit) { new ForeachTreeTraverser(f).traverse(this) }
+
+ /** Find all subtrees matching predicate `p` */
+ def filter(f: Tree => Boolean): List[Tree] = {
+ val ft = new FilterTreeTraverser(f)
+ ft.traverse(this)
+ ft.hits.toList
+ }
+
+ /** Returns optionally first tree (in a preorder traversal) which satisfies predicate `p`,
+ * or None if none exists.
+ */
+ def find(p: Tree => Boolean): Option[Tree] = {
+ val ft = new FindTreeTraverser(p)
+ ft.traverse(this)
+ ft.result
+ }
+
+ /** Is there part of this tree which satisfies predicate `p`? */
+ def exists(p: Tree => Boolean): Boolean = !find(p).isEmpty
+
+ def equalsStructure(that : Tree) = equalsStructure0(that)(_ eq _)
+ def equalsStructure0(that: Tree)(f: (Tree,Tree) => Boolean): Boolean =
+ f(this, that) || ((this.productArity == that.productArity) && {
+ def equals0(this0: Any, that0: Any): Boolean = (this0, that0) match {
+ case (x: Tree, y: Tree) => f(x, y) || (x equalsStructure0 y)(f)
+ case (xs: List[_], ys: List[_]) => (xs corresponds ys)(equals0)
+ case _ => this0 == that0
+ }
+ def compareOriginals() = (this, that) match {
+ case (x: TypeTree, y: TypeTree) if x.original != null && y.original != null =>
+ (x.original equalsStructure0 y.original)(f)
+ case _ =>
+ true
+ }
+
+ (this.productIterator zip that.productIterator forall { case (x, y) => equals0(x, y) }) && compareOriginals()
+ })
+
+ /** The direct child trees of this tree
+ * EmptyTrees are always omitted. Lists are collapsed.
+ */
+ def children: List[Tree] = {
+ def subtrees(x: Any): List[Tree] = x match {
+ case EmptyTree => Nil
+ case t: Tree => List(t)
+ case xs: List[_] => xs flatMap subtrees
+ case _ => Nil
+ }
+ productIterator.toList flatMap subtrees
+ }
+
+ /** Make a copy of this tree, keeping all attributes,
+ * except that all positions are focused (so nothing
+ * in this tree will be found when searching by position).
+ */
+ def duplicate: this.type =
+ duplicateTree(this).asInstanceOf[this.type]
+
+ private[scala] def copyAttrs(tree: Tree): this.type = {
+ pos = tree.pos
+ tpe = tree.tpe
+ if (hasSymbol) symbol = tree.symbol
+ this
+ }
+
+ override def toString: String = show(this)
+ override def hashCode(): Int = System.identityHashCode(this)
+ override def equals(that: Any) = this eq that.asInstanceOf[AnyRef]
+ }
+
+ /** Hook to define what toString means on a tree
+ */
+ def show(tree: Tree): String
+
+ trait SymTree extends Tree {
+ override def hasSymbol = true
+ override var symbol: Symbol = NoSymbol
+ }
+
+ trait RefTree extends SymTree {
+ def name: Name
+ }
+
+ abstract class DefTree extends SymTree {
+ def name: Name
+ override def isDef = true
+ }
+
+ trait TermTree extends Tree
+
+ /** A tree for a type. Note that not all type trees implement
+ * this trait; in particular, Ident's are an exception. */
+ trait TypTree extends Tree
+
+// ----- tree node alternatives --------------------------------------
+
+ /** The empty tree */
+ case object EmptyTree extends TermTree {
+ super.tpe_=(NoType)
+ override def tpe_=(t: Type) =
+ if (t != NoType) throw new UnsupportedOperationException("tpe_=("+t+") inapplicable for <empty>")
+ override def isEmpty = true
+ }
+
+ abstract class MemberDef extends DefTree {
+ def mods: Modifiers
+ def keyword: String = this match {
+ case TypeDef(_, _, _, _) => "type"
+ case ClassDef(mods, _, _, _) => if (mods hasModifier Modifier.`trait`) "trait" else "class"
+ case DefDef(_, _, _, _, _, _) => "def"
+ case ModuleDef(_, _, _) => "object"
+ case PackageDef(_, _) => "package"
+ case ValDef(mods, _, _, _) => if (mods hasModifier Modifier.mutable) "var" else "val"
+ case _ => ""
+ }
+ // final def hasFlag(mask: Long): Boolean = mods hasFlag mask
+ }
+
+ /** Package clause
+ */
+ case class PackageDef(pid: RefTree, stats: List[Tree])
+ extends MemberDef {
+ def name = pid.name
+ def mods = Modifiers()
+ }
+
+ abstract class ImplDef extends MemberDef {
+ def impl: Template
+ }
+
+ /** Class definition */
+ case class ClassDef(mods: Modifiers, name: TypeName, tparams: List[TypeDef], impl: Template)
+ extends ImplDef
+
+ /** Singleton object definition
+ */
+ case class ModuleDef(mods: Modifiers, name: TermName, impl: Template)
+ extends ImplDef
+
+ abstract class ValOrDefDef extends MemberDef {
+ def name: TermName
+ def tpt: Tree
+ def rhs: Tree
+ }
+
+ /** Value definition
+ */
+ case class ValDef(mods: Modifiers, name: TermName, tpt: Tree, rhs: Tree) extends ValOrDefDef
+
+ /** Method definition
+ */
+ case class DefDef(mods: Modifiers, name: TermName, tparams: List[TypeDef],
+ vparamss: List[List[ValDef]], tpt: Tree, rhs: Tree) extends ValOrDefDef
+
+ /** Abstract type, type parameter, or type alias */
+ case class TypeDef(mods: Modifiers, name: TypeName, tparams: List[TypeDef], rhs: Tree)
+ extends MemberDef
+
+ /** <p>
+ * Labelled expression - the symbols in the array (must be Idents!)
+ * are those the label takes as argument
+ * </p>
+ * <p>
+ * The symbol that is given to the labeldef should have a MethodType
+ * (as if it were a nested function)
+ * </p>
+ * <p>
+ * Jumps are apply nodes attributed with label symbol, the arguments
+ * will get assigned to the idents.
+ * </p>
+ * <p>
+ * Note: on 2005-06-09 Martin, Iuli, Burak agreed to have forward
+ * jumps within a Block.
+ * </p>
+ */
+ case class LabelDef(name: TermName, params: List[Ident], rhs: Tree)
+ extends DefTree with TermTree
+
+
+ /** Import selector
+ *
+ * Representation of an imported name its optional rename and their optional positions
+ *
+ * @param name the imported name
+ * @param namePos its position or -1 if undefined
+ * @param rename the name the import is renamed to (== name if no renaming)
+ * @param renamePos the position of the rename or -1 if undefined
+ */
+ case class ImportSelector(name: Name, namePos: Int, rename: Name, renamePos: Int)
+
+ /** Import clause
+ *
+ * @param expr
+ * @param selectors
+ */
+ case class Import(expr: Tree, selectors: List[ImportSelector])
+ extends SymTree
+ // The symbol of an Import is an import symbol @see Symbol.newImport
+ // It's used primarily as a marker to check that the import has been typechecked.
+
+ /** Instantiation template of a class or trait
+ *
+ * @param parents
+ * @param body
+ */
+ case class Template(parents: List[Tree], self: ValDef, body: List[Tree])
+ extends SymTree {
+ // the symbol of a template is a local dummy. @see Symbol.newLocalDummy
+ // the owner of the local dummy is the enclosing trait or class.
+ // the local dummy is itself the owner of any local blocks
+ // For example:
+ //
+ // class C {
+ // def foo // owner is C
+ // {
+ // def bar // owner is local dummy
+ // }
+ // System.err.println("TEMPLATE: " + parents)
+ }
+
+ /** Block of expressions (semicolon separated expressions) */
+ case class Block(stats: List[Tree], expr: Tree)
+ extends TermTree
+
+ /** Case clause in a pattern match, eliminated during explicitouter
+ * (except for occurrences in switch statements)
+ */
+ case class CaseDef(pat: Tree, guard: Tree, body: Tree)
+ extends Tree
+
+ /** Alternatives of patterns, eliminated by explicitouter, except for
+ * occurrences in encoded Switch stmt (=remaining Match(CaseDef(...))
+ */
+ case class Alternative(trees: List[Tree])
+ extends TermTree
+
+ /** Repetition of pattern, eliminated by explicitouter */
+ case class Star(elem: Tree)
+ extends TermTree
+
+ /** Bind of a variable to a rhs pattern, eliminated by explicitouter
+ *
+ * @param name
+ * @param body
+ */
+ case class Bind(name: Name, body: Tree)
+ extends DefTree
+
+ case class UnApply(fun: Tree, args: List[Tree])
+ extends TermTree
+
+ /** Array of expressions, needs to be translated in backend,
+ */
+ case class ArrayValue(elemtpt: Tree, elems: List[Tree])
+ extends TermTree
+
+ /** Anonymous function, eliminated by analyzer */
+ case class Function(vparams: List[ValDef], body: Tree)
+ extends TermTree with SymTree
+ // The symbol of a Function is a synthetic value of name nme.ANON_FUN_NAME
+ // It is the owner of the function's parameters.
+
+ /** Assignment */
+ case class Assign(lhs: Tree, rhs: Tree)
+ extends TermTree
+
+ /** Conditional expression */
+ case class If(cond: Tree, thenp: Tree, elsep: Tree)
+ extends TermTree
+
+ /** <p>
+ * Pattern matching expression (before explicitouter)
+ * Switch statements (after explicitouter)
+ * </p>
+ * <p>
+ * After explicitouter, cases will satisfy the following constraints:
+ * </p>
+ * <ul>
+ * <li>all guards are EmptyTree,</li>
+ * <li>all patterns will be either <code>Literal(Constant(x:Int))</code>
+ * or <code>Alternative(lit|...|lit)</code></li>
+ * <li>except for an "otherwise" branch, which has pattern
+ * <code>Ident(nme.WILDCARD)</code></li>
+ * </ul>
+ */
+ case class Match(selector: Tree, cases: List[CaseDef])
+ extends TermTree
+
+ /** Return expression */
+ case class Return(expr: Tree)
+ extends TermTree with SymTree
+ // The symbol of a Return node is the enclosing method.
+
+ case class Try(block: Tree, catches: List[CaseDef], finalizer: Tree)
+ extends TermTree
+
+ /** Throw expression */
+ case class Throw(expr: Tree)
+ extends TermTree
+
+ /** Object instantiation
+ * One should always use factory method below to build a user level new.
+ *
+ * @param tpt a class type
+ */
+ case class New(tpt: Tree) extends TermTree
+
+ /** Type annotation, eliminated by explicit outer */
+ case class Typed(expr: Tree, tpt: Tree)
+ extends TermTree
+
+ // Martin to Sean: Should GenericApply/TypeApply/Apply not be SymTree's? After all,
+ // ApplyDynamic is a SymTree.
+ abstract class GenericApply extends TermTree {
+ val fun: Tree
+ val args: List[Tree]
+ }
+
+ /** Type application */
+ case class TypeApply(fun: Tree, args: List[Tree])
+ extends GenericApply {
+ override def symbol: Symbol = fun.symbol
+ override def symbol_=(sym: Symbol) { fun.symbol = sym }
+ }
+
+ /** Value application */
+ case class Apply(fun: Tree, args: List[Tree])
+ extends GenericApply {
+ override def symbol: Symbol = fun.symbol
+ override def symbol_=(sym: Symbol) { fun.symbol = sym }
+ }
+
+ class ApplyToImplicitArgs(fun: Tree, args: List[Tree]) extends Apply(fun, args)
+
+ class ApplyImplicitView(fun: Tree, args: List[Tree]) extends Apply(fun, args)
+
+ /** Dynamic value application.
+ * In a dynamic application q.f(as)
+ * - q is stored in qual
+ * - as is stored in args
+ * - f is stored as the node's symbol field.
+ */
+ case class ApplyDynamic(qual: Tree, args: List[Tree])
+ extends TermTree with SymTree
+ // The symbol of an ApplyDynamic is the function symbol of `qual`, or NoSymbol, if there is none.
+
+ /** Super reference, qual = corresponding this reference */
+ case class Super(qual: Tree, mix: TypeName) extends TermTree {
+ // The symbol of a Super is the class _from_ which the super reference is made.
+ // For instance in C.super(...), it would be C.
+ override def symbol: Symbol = qual.symbol
+ override def symbol_=(sym: Symbol) { qual.symbol = sym }
+ }
+
+ /** Self reference */
+ case class This(qual: TypeName)
+ extends TermTree with SymTree
+ // The symbol of a This is the class to which the this refers.
+ // For instance in C.this, it would be C.
+
+ /** Designator <qualifier> . <name> */
+ case class Select(qualifier: Tree, name: Name)
+ extends RefTree
+
+ /** Identifier <name> */
+ case class Ident(name: Name) extends RefTree { }
+
+ class BackQuotedIdent(name: Name) extends Ident(name)
+
+ /** Literal */
+ case class Literal(value: Constant)
+ extends TermTree {
+ assert(value ne null)
+ }
+
+ def Literal(value: Any): Literal =
+ Literal(Constant(value))
+
+ /** A tree that has an annotation attached to it. Only used for annotated types and
+ * annotation ascriptions, annotations on definitions are stored in the Modifiers.
+ * Eliminated by typechecker (typedAnnotated), the annotations are then stored in
+ * an AnnotatedType.
+ */
+ case class Annotated(annot: Tree, arg: Tree) extends Tree
+
+ /** Singleton type, eliminated by RefCheck */
+ case class SingletonTypeTree(ref: Tree)
+ extends TypTree
+
+ /** Type selection <qualifier> # <name>, eliminated by RefCheck */
+ case class SelectFromTypeTree(qualifier: Tree, name: TypeName)
+ extends TypTree with RefTree
+
+ /** Intersection type <parent1> with ... with <parentN> { <decls> }, eliminated by RefCheck */
+ case class CompoundTypeTree(templ: Template)
+ extends TypTree
+
+ /** Applied type <tpt> [ <args> ], eliminated by RefCheck */
+ case class AppliedTypeTree(tpt: Tree, args: List[Tree])
+ extends TypTree {
+ override def symbol: Symbol = tpt.symbol
+ override def symbol_=(sym: Symbol) { tpt.symbol = sym }
+ }
+
+ case class TypeBoundsTree(lo: Tree, hi: Tree)
+ extends TypTree
+
+ case class ExistentialTypeTree(tpt: Tree, whereClauses: List[Tree])
+ extends TypTree
+
+ /** A synthetic tree holding an arbitrary type. Not to be confused with
+ * with TypTree, the trait for trees that are only used for type trees.
+ * TypeTree's are inserted in several places, but most notably in
+ * `RefCheck`, where the arbitrary type trees are all replaced by
+ * TypeTree's. */
+ case class TypeTree() extends TypTree {
+ private var orig: Tree = null
+ private[scala] var wasEmpty: Boolean = false
+
+ override def symbol = if (tpe == null) null else tpe.typeSymbol
+ override def isEmpty = (tpe eq null) || tpe == NoType
+
+ def original: Tree = orig
+ def setOriginal(tree: Tree): this.type = {
+ def followOriginal(t: Tree): Tree = t match {
+ case tt: TypeTree => followOriginal(tt.original)
+ case t => t
+ }
+
+ orig = followOriginal(tree); setPos(tree.pos);
+ this
+ }
+
+ override def defineType(tp: Type): this.type = {
+ wasEmpty = isEmpty
+ setType(tp)
+ }
+ }
+
+ def TypeTree(tp: Type): TypeTree = TypeTree() setType tp
+
+ // ------ traversers, copiers, and transformers ---------------------------------------------
+
+ val treeCopy = newLazyTreeCopier
+
+ class Traverser {
+ protected var currentOwner: Symbol = definitions.RootClass
+
+ def traverse(tree: Tree): Unit = tree match {
+ case EmptyTree =>
+ ;
+ case PackageDef(pid, stats) =>
+ traverse(pid)
+ atOwner(tree.symbol.moduleClass) {
+ traverseTrees(stats)
+ }
+ case ClassDef(mods, name, tparams, impl) =>
+ atOwner(tree.symbol) {
+ traverseTrees(mods.annotations); traverseTrees(tparams); traverse(impl)
+ }
+ case ModuleDef(mods, name, impl) =>
+ atOwner(tree.symbol.moduleClass) {
+ traverseTrees(mods.annotations); traverse(impl)
+ }
+ case ValDef(mods, name, tpt, rhs) =>
+ atOwner(tree.symbol) {
+ traverseTrees(mods.annotations); traverse(tpt); traverse(rhs)
+ }
+ case DefDef(mods, name, tparams, vparamss, tpt, rhs) =>
+ atOwner(tree.symbol) {
+ traverseTrees(mods.annotations); traverseTrees(tparams); traverseTreess(vparamss); traverse(tpt); traverse(rhs)
+ }
+ case TypeDef(mods, name, tparams, rhs) =>
+ atOwner(tree.symbol) {
+ traverseTrees(mods.annotations); traverseTrees(tparams); traverse(rhs)
+ }
+ case LabelDef(name, params, rhs) =>
+ traverseTrees(params); traverse(rhs)
+ case Import(expr, selectors) =>
+ traverse(expr)
+ case Annotated(annot, arg) =>
+ traverse(annot); traverse(arg)
+ case Template(parents, self, body) =>
+ traverseTrees(parents)
+ if (!self.isEmpty) traverse(self)
+ traverseStats(body, tree.symbol)
+ case Block(stats, expr) =>
+ traverseTrees(stats); traverse(expr)
+ case CaseDef(pat, guard, body) =>
+ traverse(pat); traverse(guard); traverse(body)
+ case Alternative(trees) =>
+ traverseTrees(trees)
+ case Star(elem) =>
+ traverse(elem)
+ case Bind(name, body) =>
+ traverse(body)
+ case UnApply(fun, args) =>
+ traverse(fun); traverseTrees(args)
+ case ArrayValue(elemtpt, trees) =>
+ traverse(elemtpt); traverseTrees(trees)
+ case Function(vparams, body) =>
+ atOwner(tree.symbol) {
+ traverseTrees(vparams); traverse(body)
+ }
+ case Assign(lhs, rhs) =>
+ traverse(lhs); traverse(rhs)
+ case If(cond, thenp, elsep) =>
+ traverse(cond); traverse(thenp); traverse(elsep)
+ case Match(selector, cases) =>
+ traverse(selector); traverseTrees(cases)
+ case Return(expr) =>
+ traverse(expr)
+ case Try(block, catches, finalizer) =>
+ traverse(block); traverseTrees(catches); traverse(finalizer)
+ case Throw(expr) =>
+ traverse(expr)
+ case New(tpt) =>
+ traverse(tpt)
+ case Typed(expr, tpt) =>
+ traverse(expr); traverse(tpt)
+ case TypeApply(fun, args) =>
+ traverse(fun); traverseTrees(args)
+ case Apply(fun, args) =>
+ traverse(fun); traverseTrees(args)
+ case ApplyDynamic(qual, args) =>
+ traverse(qual); traverseTrees(args)
+ case Super(qual, _) =>
+ traverse(qual)
+ case This(_) =>
+ ;
+ case Select(qualifier, selector) =>
+ traverse(qualifier)
+ case Ident(_) =>
+ ;
+ case Literal(_) =>
+ ;
+ case TypeTree() =>
+ ;
+ case SingletonTypeTree(ref) =>
+ traverse(ref)
+ case SelectFromTypeTree(qualifier, selector) =>
+ traverse(qualifier)
+ case CompoundTypeTree(templ) =>
+ traverse(templ)
+ case AppliedTypeTree(tpt, args) =>
+ traverse(tpt); traverseTrees(args)
+ case TypeBoundsTree(lo, hi) =>
+ traverse(lo); traverse(hi)
+ case ExistentialTypeTree(tpt, whereClauses) =>
+ traverse(tpt); traverseTrees(whereClauses)
+ case _ => xtraverse(this, tree)
+ }
+
+ def traverseTrees(trees: List[Tree]) {
+ trees foreach traverse
+ }
+ def traverseTreess(treess: List[List[Tree]]) {
+ treess foreach traverseTrees
+ }
+ def traverseStats(stats: List[Tree], exprOwner: Symbol) {
+ stats foreach (stat =>
+ if (exprOwner != currentOwner) atOwner(exprOwner)(traverse(stat))
+ else traverse(stat)
+ )
+ }
+
+ def atOwner(owner: Symbol)(traverse: => Unit) {
+ val prevOwner = currentOwner
+ currentOwner = owner
+ traverse
+ currentOwner = prevOwner
+ }
+
+ /** Leave apply available in the generic traverser to do something else.
+ */
+ def apply[T <: Tree](tree: T): T = { traverse(tree); tree }
+ }
+
+ protected def xtraverse(traverser: Traverser, tree: Tree): Unit = throw new MatchError(tree)
+
+ // to be implemented in subclasses:
+ type TreeCopier <: TreeCopierOps
+ def newStrictTreeCopier: TreeCopier
+ def newLazyTreeCopier: TreeCopier
+
+ trait TreeCopierOps {
+ def ClassDef(tree: Tree, mods: Modifiers, name: Name, tparams: List[TypeDef], impl: Template): ClassDef
+ def PackageDef(tree: Tree, pid: RefTree, stats: List[Tree]): PackageDef
+ def ModuleDef(tree: Tree, mods: Modifiers, name: Name, impl: Template): ModuleDef
+ def ValDef(tree: Tree, mods: Modifiers, name: Name, tpt: Tree, rhs: Tree): ValDef
+ def DefDef(tree: Tree, mods: Modifiers, name: Name, tparams: List[TypeDef], vparamss: List[List[ValDef]], tpt: Tree, rhs: Tree): DefDef
+ def TypeDef(tree: Tree, mods: Modifiers, name: Name, tparams: List[TypeDef], rhs: Tree): TypeDef
+ def LabelDef(tree: Tree, name: Name, params: List[Ident], rhs: Tree): LabelDef
+ def Import(tree: Tree, expr: Tree, selectors: List[ImportSelector]): Import
+ def Template(tree: Tree, parents: List[Tree], self: ValDef, body: List[Tree]): Template
+ def Block(tree: Tree, stats: List[Tree], expr: Tree): Block
+ def CaseDef(tree: Tree, pat: Tree, guard: Tree, body: Tree): CaseDef
+ def Alternative(tree: Tree, trees: List[Tree]): Alternative
+ def Star(tree: Tree, elem: Tree): Star
+ def Bind(tree: Tree, name: Name, body: Tree): Bind
+ def UnApply(tree: Tree, fun: Tree, args: List[Tree]): UnApply
+ def ArrayValue(tree: Tree, elemtpt: Tree, trees: List[Tree]): ArrayValue
+ def Function(tree: Tree, vparams: List[ValDef], body: Tree): Function
+ def Assign(tree: Tree, lhs: Tree, rhs: Tree): Assign
+ def If(tree: Tree, cond: Tree, thenp: Tree, elsep: Tree): If
+ def Match(tree: Tree, selector: Tree, cases: List[CaseDef]): Match
+ def Return(tree: Tree, expr: Tree): Return
+ def Try(tree: Tree, block: Tree, catches: List[CaseDef], finalizer: Tree): Try
+ def Throw(tree: Tree, expr: Tree): Throw
+ def New(tree: Tree, tpt: Tree): New
+ def Typed(tree: Tree, expr: Tree, tpt: Tree): Typed
+ def TypeApply(tree: Tree, fun: Tree, args: List[Tree]): TypeApply
+ def Apply(tree: Tree, fun: Tree, args: List[Tree]): Apply
+ def ApplyDynamic(tree: Tree, qual: Tree, args: List[Tree]): ApplyDynamic
+ def Super(tree: Tree, qual: Tree, mix: TypeName): Super
+ def This(tree: Tree, qual: Name): This
+ def Select(tree: Tree, qualifier: Tree, selector: Name): Select
+ def Ident(tree: Tree, name: Name): Ident
+ def Literal(tree: Tree, value: Constant): Literal
+ def TypeTree(tree: Tree): TypeTree
+ def Annotated(tree: Tree, annot: Tree, arg: Tree): Annotated
+ def SingletonTypeTree(tree: Tree, ref: Tree): SingletonTypeTree
+ def SelectFromTypeTree(tree: Tree, qualifier: Tree, selector: Name): SelectFromTypeTree
+ def CompoundTypeTree(tree: Tree, templ: Template): CompoundTypeTree
+ def AppliedTypeTree(tree: Tree, tpt: Tree, args: List[Tree]): AppliedTypeTree
+ def TypeBoundsTree(tree: Tree, lo: Tree, hi: Tree): TypeBoundsTree
+ def ExistentialTypeTree(tree: Tree, tpt: Tree, whereClauses: List[Tree]): ExistentialTypeTree
+ }
+
+ class StrictTreeCopier extends TreeCopierOps {
+ def ClassDef(tree: Tree, mods: Modifiers, name: Name, tparams: List[TypeDef], impl: Template) =
+ new ClassDef(mods, name.toTypeName, tparams, impl).copyAttrs(tree)
+ def PackageDef(tree: Tree, pid: RefTree, stats: List[Tree]) =
+ new PackageDef(pid, stats).copyAttrs(tree)
+ def ModuleDef(tree: Tree, mods: Modifiers, name: Name, impl: Template) =
+ new ModuleDef(mods, name, impl).copyAttrs(tree)
+ def ValDef(tree: Tree, mods: Modifiers, name: Name, tpt: Tree, rhs: Tree) =
+ new ValDef(mods, name, tpt, rhs).copyAttrs(tree)
+ def DefDef(tree: Tree, mods: Modifiers, name: Name, tparams: List[TypeDef], vparamss: List[List[ValDef]], tpt: Tree, rhs: Tree) =
+ new DefDef(mods, name, tparams, vparamss, tpt, rhs).copyAttrs(tree)
+ def TypeDef(tree: Tree, mods: Modifiers, name: Name, tparams: List[TypeDef], rhs: Tree) =
+ new TypeDef(mods, name.toTypeName, tparams, rhs).copyAttrs(tree)
+ def LabelDef(tree: Tree, name: Name, params: List[Ident], rhs: Tree) =
+ new LabelDef(name, params, rhs).copyAttrs(tree)
+ def Import(tree: Tree, expr: Tree, selectors: List[ImportSelector]) =
+ new Import(expr, selectors).copyAttrs(tree)
+ def Template(tree: Tree, parents: List[Tree], self: ValDef, body: List[Tree]) =
+ new Template(parents, self, body).copyAttrs(tree)
+ def Block(tree: Tree, stats: List[Tree], expr: Tree) =
+ new Block(stats, expr).copyAttrs(tree)
+ def CaseDef(tree: Tree, pat: Tree, guard: Tree, body: Tree) =
+ new CaseDef(pat, guard, body).copyAttrs(tree)
+ def Alternative(tree: Tree, trees: List[Tree]) =
+ new Alternative(trees).copyAttrs(tree)
+ def Star(tree: Tree, elem: Tree) =
+ new Star(elem).copyAttrs(tree)
+ def Bind(tree: Tree, name: Name, body: Tree) =
+ new Bind(name, body).copyAttrs(tree)
+ def UnApply(tree: Tree, fun: Tree, args: List[Tree]) =
+ new UnApply(fun, args).copyAttrs(tree)
+ def ArrayValue(tree: Tree, elemtpt: Tree, trees: List[Tree]) =
+ new ArrayValue(elemtpt, trees).copyAttrs(tree)
+ def Function(tree: Tree, vparams: List[ValDef], body: Tree) =
+ new Function(vparams, body).copyAttrs(tree)
+ def Assign(tree: Tree, lhs: Tree, rhs: Tree) =
+ new Assign(lhs, rhs).copyAttrs(tree)
+ def If(tree: Tree, cond: Tree, thenp: Tree, elsep: Tree) =
+ new If(cond, thenp, elsep).copyAttrs(tree)
+ def Match(tree: Tree, selector: Tree, cases: List[CaseDef]) =
+ new Match(selector, cases).copyAttrs(tree)
+ def Return(tree: Tree, expr: Tree) =
+ new Return(expr).copyAttrs(tree)
+ def Try(tree: Tree, block: Tree, catches: List[CaseDef], finalizer: Tree) =
+ new Try(block, catches, finalizer).copyAttrs(tree)
+ def Throw(tree: Tree, expr: Tree) =
+ new Throw(expr).copyAttrs(tree)
+ def New(tree: Tree, tpt: Tree) =
+ new New(tpt).copyAttrs(tree)
+ def Typed(tree: Tree, expr: Tree, tpt: Tree) =
+ new Typed(expr, tpt).copyAttrs(tree)
+ def TypeApply(tree: Tree, fun: Tree, args: List[Tree]) =
+ new TypeApply(fun, args).copyAttrs(tree)
+ def Apply(tree: Tree, fun: Tree, args: List[Tree]) =
+ (tree match {
+ case _: ApplyToImplicitArgs => new ApplyToImplicitArgs(fun, args)
+ case _: ApplyImplicitView => new ApplyImplicitView(fun, args)
+ case _ => new Apply(fun, args)
+ }).copyAttrs(tree)
+ def ApplyDynamic(tree: Tree, qual: Tree, args: List[Tree]) =
+ new ApplyDynamic(qual, args).copyAttrs(tree)
+ def Super(tree: Tree, qual: Tree, mix: TypeName) =
+ new Super(qual, mix).copyAttrs(tree)
+ def This(tree: Tree, qual: Name) =
+ new This(qual.toTypeName).copyAttrs(tree)
+ def Select(tree: Tree, qualifier: Tree, selector: Name) =
+ new Select(qualifier, selector).copyAttrs(tree)
+ def Ident(tree: Tree, name: Name) =
+ new Ident(name).copyAttrs(tree)
+ def Literal(tree: Tree, value: Constant) =
+ new Literal(value).copyAttrs(tree)
+ def TypeTree(tree: Tree) =
+ new TypeTree().copyAttrs(tree)
+ def Annotated(tree: Tree, annot: Tree, arg: Tree) =
+ new Annotated(annot, arg).copyAttrs(tree)
+ def SingletonTypeTree(tree: Tree, ref: Tree) =
+ new SingletonTypeTree(ref).copyAttrs(tree)
+ def SelectFromTypeTree(tree: Tree, qualifier: Tree, selector: Name) =
+ new SelectFromTypeTree(qualifier, selector.toTypeName).copyAttrs(tree)
+ def CompoundTypeTree(tree: Tree, templ: Template) =
+ new CompoundTypeTree(templ).copyAttrs(tree)
+ def AppliedTypeTree(tree: Tree, tpt: Tree, args: List[Tree]) =
+ new AppliedTypeTree(tpt, args).copyAttrs(tree)
+ def TypeBoundsTree(tree: Tree, lo: Tree, hi: Tree) =
+ new TypeBoundsTree(lo, hi).copyAttrs(tree)
+ def ExistentialTypeTree(tree: Tree, tpt: Tree, whereClauses: List[Tree]) =
+ new ExistentialTypeTree(tpt, whereClauses).copyAttrs(tree)
+ }
+
+ class LazyTreeCopier extends TreeCopierOps {
+ val treeCopy: TreeCopier = newStrictTreeCopier
+ def ClassDef(tree: Tree, mods: Modifiers, name: Name, tparams: List[TypeDef], impl: Template) = tree match {
+ case t @ ClassDef(mods0, name0, tparams0, impl0)
+ if (mods0 == mods) && (name0 == name) && (tparams0 == tparams) && (impl0 == impl) => t
+ case _ => treeCopy.ClassDef(tree, mods, name, tparams, impl)
+ }
+ def PackageDef(tree: Tree, pid: RefTree, stats: List[Tree]) = tree match {
+ case t @ PackageDef(pid0, stats0)
+ if (pid0 == pid) && (stats0 == stats) => t
+ case _ => treeCopy.PackageDef(tree, pid, stats)
+ }
+ def ModuleDef(tree: Tree, mods: Modifiers, name: Name, impl: Template) = tree match {
+ case t @ ModuleDef(mods0, name0, impl0)
+ if (mods0 == mods) && (name0 == name) && (impl0 == impl) => t
+ case _ => treeCopy.ModuleDef(tree, mods, name, impl)
+ }
+ def ValDef(tree: Tree, mods: Modifiers, name: Name, tpt: Tree, rhs: Tree) = tree match {
+ case t @ ValDef(mods0, name0, tpt0, rhs0)
+ if (mods0 == mods) && (name0 == name) && (tpt0 == tpt) && (rhs0 == rhs) => t
+ case _ => treeCopy.ValDef(tree, mods, name, tpt, rhs)
+ }
+ def DefDef(tree: Tree, mods: Modifiers, name: Name, tparams: List[TypeDef], vparamss: List[List[ValDef]], tpt: Tree, rhs: Tree) = tree match {
+ case t @ DefDef(mods0, name0, tparams0, vparamss0, tpt0, rhs0)
+ if (mods0 == mods) && (name0 == name) && (tparams0 == tparams) &&
+ (vparamss0 == vparamss) && (tpt0 == tpt) && (rhs == rhs0) => t
+ case _ => treeCopy.DefDef(tree, mods, name, tparams, vparamss, tpt, rhs)
+ }
+ def TypeDef(tree: Tree, mods: Modifiers, name: Name, tparams: List[TypeDef], rhs: Tree) = tree match {
+ case t @ TypeDef(mods0, name0, tparams0, rhs0)
+ if (mods0 == mods) && (name0 == name) && (tparams0 == tparams) && (rhs0 == rhs) => t
+ case _ => treeCopy.TypeDef(tree, mods, name, tparams, rhs)
+ }
+ def LabelDef(tree: Tree, name: Name, params: List[Ident], rhs: Tree) = tree match {
+ case t @ LabelDef(name0, params0, rhs0)
+ if (name0 == name) && (params0 == params) && (rhs0 == rhs) => t
+ case _ => treeCopy.LabelDef(tree, name, params, rhs)
+ }
+ def Import(tree: Tree, expr: Tree, selectors: List[ImportSelector]) = tree match {
+ case t @ Import(expr0, selectors0)
+ if (expr0 == expr) && (selectors0 == selectors) => t
+ case _ => treeCopy.Import(tree, expr, selectors)
+ }
+ def Template(tree: Tree, parents: List[Tree], self: ValDef, body: List[Tree]) = tree match {
+ case t @ Template(parents0, self0, body0)
+ if (parents0 == parents) && (self0 == self) && (body0 == body) => t
+ case _ => treeCopy.Template(tree, parents, self, body)
+ }
+ def Block(tree: Tree, stats: List[Tree], expr: Tree) = tree match {
+ case t @ Block(stats0, expr0)
+ if ((stats0 == stats) && (expr0 == expr)) => t
+ case _ => treeCopy.Block(tree, stats, expr)
+ }
+ def CaseDef(tree: Tree, pat: Tree, guard: Tree, body: Tree) = tree match {
+ case t @ CaseDef(pat0, guard0, body0)
+ if (pat0 == pat) && (guard0 == guard) && (body0 == body) => t
+ case _ => treeCopy.CaseDef(tree, pat, guard, body)
+ }
+ def Alternative(tree: Tree, trees: List[Tree]) = tree match {
+ case t @ Alternative(trees0)
+ if trees0 == trees => t
+ case _ => treeCopy.Alternative(tree, trees)
+ }
+ def Star(tree: Tree, elem: Tree) = tree match {
+ case t @ Star(elem0)
+ if elem0 == elem => t
+ case _ => treeCopy.Star(tree, elem)
+ }
+ def Bind(tree: Tree, name: Name, body: Tree) = tree match {
+ case t @ Bind(name0, body0)
+ if (name0 == name) && (body0 == body) => t
+ case _ => treeCopy.Bind(tree, name, body)
+ }
+ def UnApply(tree: Tree, fun: Tree, args: List[Tree]) = tree match {
+ case t @ UnApply(fun0, args0)
+ if (fun0 == fun) && (args0 == args) => t
+ case _ => treeCopy.UnApply(tree, fun, args)
+ }
+ def ArrayValue(tree: Tree, elemtpt: Tree, trees: List[Tree]) = tree match {
+ case t @ ArrayValue(elemtpt0, trees0)
+ if (elemtpt0 == elemtpt) && (trees0 == trees) => t
+ case _ => treeCopy.ArrayValue(tree, elemtpt, trees)
+ }
+ def Function(tree: Tree, vparams: List[ValDef], body: Tree) = tree match {
+ case t @ Function(vparams0, body0)
+ if (vparams0 == vparams) && (body0 == body) => t
+ case _ => treeCopy.Function(tree, vparams, body)
+ }
+ def Assign(tree: Tree, lhs: Tree, rhs: Tree) = tree match {
+ case t @ Assign(lhs0, rhs0)
+ if (lhs0 == lhs) && (rhs0 == rhs) => t
+ case _ => treeCopy.Assign(tree, lhs, rhs)
+ }
+ def If(tree: Tree, cond: Tree, thenp: Tree, elsep: Tree) = tree match {
+ case t @ If(cond0, thenp0, elsep0)
+ if (cond0 == cond) && (thenp0 == thenp) && (elsep0 == elsep) => t
+ case _ => treeCopy.If(tree, cond, thenp, elsep)
+ }
+ def Match(tree: Tree, selector: Tree, cases: List[CaseDef]) = tree match {
+ case t @ Match(selector0, cases0)
+ if (selector0 == selector) && (cases0 == cases) => t
+ case _ => treeCopy.Match(tree, selector, cases)
+ }
+ def Return(tree: Tree, expr: Tree) = tree match {
+ case t @ Return(expr0)
+ if expr0 == expr => t
+ case _ => treeCopy.Return(tree, expr)
+ }
+ def Try(tree: Tree, block: Tree, catches: List[CaseDef], finalizer: Tree) = tree match {
+ case t @ Try(block0, catches0, finalizer0)
+ if (block0 == block) && (catches0 == catches) && (finalizer0 == finalizer) => t
+ case _ => treeCopy.Try(tree, block, catches, finalizer)
+ }
+ def Throw(tree: Tree, expr: Tree) = tree match {
+ case t @ Throw(expr0)
+ if expr0 == expr => t
+ case _ => treeCopy.Throw(tree, expr)
+ }
+ def New(tree: Tree, tpt: Tree) = tree match {
+ case t @ New(tpt0)
+ if tpt0 == tpt => t
+ case _ => treeCopy.New(tree, tpt)
+ }
+ def Typed(tree: Tree, expr: Tree, tpt: Tree) = tree match {
+ case t @ Typed(expr0, tpt0)
+ if (expr0 == expr) && (tpt0 == tpt) => t
+ case _ => treeCopy.Typed(tree, expr, tpt)
+ }
+ def TypeApply(tree: Tree, fun: Tree, args: List[Tree]) = tree match {
+ case t @ TypeApply(fun0, args0)
+ if (fun0 == fun) && (args0 == args) => t
+ case _ => treeCopy.TypeApply(tree, fun, args)
+ }
+ def Apply(tree: Tree, fun: Tree, args: List[Tree]) = tree match {
+ case t @ Apply(fun0, args0)
+ if (fun0 == fun) && (args0 == args) => t
+ case _ => treeCopy.Apply(tree, fun, args)
+ }
+ def ApplyDynamic(tree: Tree, qual: Tree, args: List[Tree]) = tree match {
+ case t @ ApplyDynamic(qual0, args0)
+ if (qual0 == qual) && (args0 == args) => t
+ case _ => treeCopy.ApplyDynamic(tree, qual, args)
+ }
+ def Super(tree: Tree, qual: Tree, mix: TypeName) = tree match {
+ case t @ Super(qual0, mix0)
+ if (qual0 == qual) && (mix0 == mix) => t
+ case _ => treeCopy.Super(tree, qual, mix)
+ }
+ def This(tree: Tree, qual: Name) = tree match {
+ case t @ This(qual0)
+ if qual0 == qual => t
+ case _ => treeCopy.This(tree, qual)
+ }
+ def Select(tree: Tree, qualifier: Tree, selector: Name) = tree match {
+ case t @ Select(qualifier0, selector0)
+ if (qualifier0 == qualifier) && (selector0 == selector) => t
+ case _ => treeCopy.Select(tree, qualifier, selector)
+ }
+ def Ident(tree: Tree, name: Name) = tree match {
+ case t @ Ident(name0)
+ if name0 == name => t
+ case _ => treeCopy.Ident(tree, name)
+ }
+ def Literal(tree: Tree, value: Constant) = tree match {
+ case t @ Literal(value0)
+ if value0 == value => t
+ case _ => treeCopy.Literal(tree, value)
+ }
+ def TypeTree(tree: Tree) = tree match {
+ case t @ TypeTree() => t
+ case _ => treeCopy.TypeTree(tree)
+ }
+ def Annotated(tree: Tree, annot: Tree, arg: Tree) = tree match {
+ case t @ Annotated(annot0, arg0)
+ if (annot0==annot) => t
+ case _ => treeCopy.Annotated(tree, annot, arg)
+ }
+ def SingletonTypeTree(tree: Tree, ref: Tree) = tree match {
+ case t @ SingletonTypeTree(ref0)
+ if ref0 == ref => t
+ case _ => treeCopy.SingletonTypeTree(tree, ref)
+ }
+ def SelectFromTypeTree(tree: Tree, qualifier: Tree, selector: Name) = tree match {
+ case t @ SelectFromTypeTree(qualifier0, selector0)
+ if (qualifier0 == qualifier) && (selector0 == selector) => t
+ case _ => treeCopy.SelectFromTypeTree(tree, qualifier, selector)
+ }
+ def CompoundTypeTree(tree: Tree, templ: Template) = tree match {
+ case t @ CompoundTypeTree(templ0)
+ if templ0 == templ => t
+ case _ => treeCopy.CompoundTypeTree(tree, templ)
+ }
+ def AppliedTypeTree(tree: Tree, tpt: Tree, args: List[Tree]) = tree match {
+ case t @ AppliedTypeTree(tpt0, args0)
+ if (tpt0 == tpt) && (args0 == args) => t
+ case _ => treeCopy.AppliedTypeTree(tree, tpt, args)
+ }
+ def TypeBoundsTree(tree: Tree, lo: Tree, hi: Tree) = tree match {
+ case t @ TypeBoundsTree(lo0, hi0)
+ if (lo0 == lo) && (hi0 == hi) => t
+ case _ => treeCopy.TypeBoundsTree(tree, lo, hi)
+ }
+ def ExistentialTypeTree(tree: Tree, tpt: Tree, whereClauses: List[Tree]) = tree match {
+ case t @ ExistentialTypeTree(tpt0, whereClauses0)
+ if (tpt0 == tpt) && (whereClauses0 == whereClauses) => t
+ case _ => treeCopy.ExistentialTypeTree(tree, tpt, whereClauses)
+ }
+ }
+
+ abstract class Transformer {
+ val treeCopy: TreeCopier = newLazyTreeCopier
+ protected var currentOwner: Symbol = definitions.RootClass
+ protected def currentMethod = currentOwner.enclMethod
+ protected def currentClass = currentOwner.enclClass
+ protected def currentPackage = currentOwner.toplevelClass.owner
+ def transform(tree: Tree): Tree = tree match {
+ case EmptyTree =>
+ tree
+ case PackageDef(pid, stats) =>
+ treeCopy.PackageDef(
+ tree, transform(pid).asInstanceOf[RefTree],
+ atOwner(tree.symbol.moduleClass) {
+ transformStats(stats, currentOwner)
+ }
+ )
+ case ClassDef(mods, name, tparams, impl) =>
+ atOwner(tree.symbol) {
+ treeCopy.ClassDef(tree, transformModifiers(mods), name,
+ transformTypeDefs(tparams), transformTemplate(impl))
+ }
+ case ModuleDef(mods, name, impl) =>
+ atOwner(tree.symbol.moduleClass) {
+ treeCopy.ModuleDef(tree, transformModifiers(mods),
+ name, transformTemplate(impl))
+ }
+ case ValDef(mods, name, tpt, rhs) =>
+ atOwner(tree.symbol) {
+ treeCopy.ValDef(tree, transformModifiers(mods),
+ name, transform(tpt), transform(rhs))
+ }
+ case DefDef(mods, name, tparams, vparamss, tpt, rhs) =>
+ atOwner(tree.symbol) {
+ treeCopy.DefDef(tree, transformModifiers(mods), name,
+ transformTypeDefs(tparams), transformValDefss(vparamss),
+ transform(tpt), transform(rhs))
+ }
+ case TypeDef(mods, name, tparams, rhs) =>
+ atOwner(tree.symbol) {
+ treeCopy.TypeDef(tree, transformModifiers(mods), name,
+ transformTypeDefs(tparams), transform(rhs))
+ }
+ case LabelDef(name, params, rhs) =>
+ treeCopy.LabelDef(tree, name, transformIdents(params), transform(rhs)) //bq: Martin, once, atOwner(...) works, also change `LamdaLifter.proxy'
+ case Import(expr, selectors) =>
+ treeCopy.Import(tree, transform(expr), selectors)
+ case Template(parents, self, body) =>
+ treeCopy.Template(tree, transformTrees(parents), transformValDef(self), transformStats(body, tree.symbol))
+ case Block(stats, expr) =>
+ treeCopy.Block(tree, transformStats(stats, currentOwner), transform(expr))
+ case CaseDef(pat, guard, body) =>
+ treeCopy.CaseDef(tree, transform(pat), transform(guard), transform(body))
+ case Alternative(trees) =>
+ treeCopy.Alternative(tree, transformTrees(trees))
+ case Star(elem) =>
+ treeCopy.Star(tree, transform(elem))
+ case Bind(name, body) =>
+ treeCopy.Bind(tree, name, transform(body))
+ case UnApply(fun, args) =>
+ treeCopy.UnApply(tree, fun, transformTrees(args)) // bq: see test/.../unapplyContexts2.scala
+ case ArrayValue(elemtpt, trees) =>
+ treeCopy.ArrayValue(tree, transform(elemtpt), transformTrees(trees))
+ case Function(vparams, body) =>
+ atOwner(tree.symbol) {
+ treeCopy.Function(tree, transformValDefs(vparams), transform(body))
+ }
+ case Assign(lhs, rhs) =>
+ treeCopy.Assign(tree, transform(lhs), transform(rhs))
+ case If(cond, thenp, elsep) =>
+ treeCopy.If(tree, transform(cond), transform(thenp), transform(elsep))
+ case Match(selector, cases) =>
+ treeCopy.Match(tree, transform(selector), transformCaseDefs(cases))
+ case Return(expr) =>
+ treeCopy.Return(tree, transform(expr))
+ case Try(block, catches, finalizer) =>
+ treeCopy.Try(tree, transform(block), transformCaseDefs(catches), transform(finalizer))
+ case Throw(expr) =>
+ treeCopy.Throw(tree, transform(expr))
+ case New(tpt) =>
+ treeCopy.New(tree, transform(tpt))
+ case Typed(expr, tpt) =>
+ treeCopy.Typed(tree, transform(expr), transform(tpt))
+ case TypeApply(fun, args) =>
+ treeCopy.TypeApply(tree, transform(fun), transformTrees(args))
+ case Apply(fun, args) =>
+ treeCopy.Apply(tree, transform(fun), transformTrees(args))
+ case ApplyDynamic(qual, args) =>
+ treeCopy.ApplyDynamic(tree, transform(qual), transformTrees(args))
+ case Super(qual, mix) =>
+ treeCopy.Super(tree, transform(qual), mix)
+ case This(qual) =>
+ treeCopy.This(tree, qual)
+ case Select(qualifier, selector) =>
+ treeCopy.Select(tree, transform(qualifier), selector)
+ case Ident(name) =>
+ treeCopy.Ident(tree, name)
+ case Literal(value) =>
+ treeCopy.Literal(tree, value)
+ case TypeTree() =>
+ treeCopy.TypeTree(tree)
+ case Annotated(annot, arg) =>
+ treeCopy.Annotated(tree, transform(annot), transform(arg))
+ case SingletonTypeTree(ref) =>
+ treeCopy.SingletonTypeTree(tree, transform(ref))
+ case SelectFromTypeTree(qualifier, selector) =>
+ treeCopy.SelectFromTypeTree(tree, transform(qualifier), selector)
+ case CompoundTypeTree(templ) =>
+ treeCopy.CompoundTypeTree(tree, transformTemplate(templ))
+ case AppliedTypeTree(tpt, args) =>
+ treeCopy.AppliedTypeTree(tree, transform(tpt), transformTrees(args))
+ case TypeBoundsTree(lo, hi) =>
+ treeCopy.TypeBoundsTree(tree, transform(lo), transform(hi))
+ case ExistentialTypeTree(tpt, whereClauses) =>
+ treeCopy.ExistentialTypeTree(tree, transform(tpt), transformTrees(whereClauses))
+ case _ =>
+ xtransform(this, tree)
+ }
+
+ def transformTrees(trees: List[Tree]): List[Tree] =
+ trees mapConserve (transform(_))
+ def transformTemplate(tree: Template): Template =
+ transform(tree: Tree).asInstanceOf[Template]
+ def transformTypeDefs(trees: List[TypeDef]): List[TypeDef] =
+ trees mapConserve (tree => transform(tree).asInstanceOf[TypeDef])
+ def transformValDef(tree: ValDef): ValDef =
+ if (tree.isEmpty) tree else transform(tree).asInstanceOf[ValDef]
+ def transformValDefs(trees: List[ValDef]): List[ValDef] =
+ trees mapConserve (transformValDef(_))
+ def transformValDefss(treess: List[List[ValDef]]): List[List[ValDef]] =
+ treess mapConserve (transformValDefs(_))
+ def transformCaseDefs(trees: List[CaseDef]): List[CaseDef] =
+ trees mapConserve (tree => transform(tree).asInstanceOf[CaseDef])
+ def transformIdents(trees: List[Ident]): List[Ident] =
+ trees mapConserve (tree => transform(tree).asInstanceOf[Ident])
+ def transformStats(stats: List[Tree], exprOwner: Symbol): List[Tree] =
+ stats mapConserve (stat =>
+ if (exprOwner != currentOwner && stat.isTerm) atOwner(exprOwner)(transform(stat))
+ else transform(stat)) filter (EmptyTree !=)
+ def transformModifiers(mods: Modifiers): Modifiers =
+ mods.mapAnnotations(transformTrees)
+
+ def atOwner[A](owner: Symbol)(trans: => A): A = {
+ val prevOwner = currentOwner
+ currentOwner = owner
+ val result = trans
+ currentOwner = prevOwner
+ result
+ }
+ }
+
+ protected def xtransform(transformer: Transformer, tree: Tree): Tree = throw new MatchError(tree)
+
+ class ForeachTreeTraverser(f: Tree => Unit) extends Traverser {
+ override def traverse(t: Tree) {
+ f(t)
+ super.traverse(t)
+ }
+ }
+
+ class FilterTreeTraverser(p: Tree => Boolean) extends Traverser {
+ val hits = new ListBuffer[Tree]
+ override def traverse(t: Tree) {
+ if (p(t)) hits += t
+ super.traverse(t)
+ }
+ }
+
+ class FindTreeTraverser(p: Tree => Boolean) extends Traverser {
+ var result: Option[Tree] = None
+ override def traverse(t: Tree) {
+ if (result.isEmpty) {
+ if (p(t)) result = Some(t)
+ super.traverse(t)
+ }
+ }
+ }
+
+ protected def duplicateTree(tree: Tree): Tree
+
+/* A standard pattern match
+ case EmptyTree =>
+ case PackageDef(pid, stats) =>
+ // package pid { stats }
+ case ClassDef(mods, name, tparams, impl) =>
+ // mods class name [tparams] impl where impl = extends parents { defs }
+ case ModuleDef(mods, name, impl) => (eliminated by refcheck)
+ // mods object name impl where impl = extends parents { defs }
+ case ValDef(mods, name, tpt, rhs) =>
+ // mods val name: tpt = rhs
+ // note missing type information is expressed by tpt = TypeTree()
+ case DefDef(mods, name, tparams, vparamss, tpt, rhs) =>
+ // mods def name[tparams](vparams_1)...(vparams_n): tpt = rhs
+ // note missing type information is expressed by tpt = TypeTree()
+ case TypeDef(mods, name, tparams, rhs) => (eliminated by erasure)
+ // mods type name[tparams] = rhs
+ // mods type name[tparams] >: lo <: hi, where lo, hi are in a TypeBoundsTree,
+ and DEFERRED is set in mods
+ case LabelDef(name, params, rhs) =>
+ // used for tailcalls and like
+ // while/do are desugared to label defs as follows:
+ // while (cond) body ==> LabelDef($L, List(), if (cond) { body; L$() } else ())
+ // do body while (cond) ==> LabelDef($L, List(), body; if (cond) L$() else ())
+ case Import(expr, selectors) => (eliminated by typecheck)
+ // import expr.{selectors}
+ // Selectors are a list of pairs of names (from, to).
+ // The last (and maybe only name) may be a nme.WILDCARD
+ // for instance
+ // import qual.{x, y => z, _} would be represented as
+ // Import(qual, List(("x", "x"), ("y", "z"), (WILDCARD, null)))
+ case Template(parents, self, body) =>
+ // extends parents { self => body }
+ // if self is missing it is represented as emptyValDef
+ case Block(stats, expr) =>
+ // { stats; expr }
+ case CaseDef(pat, guard, body) => (eliminated by transmatch/explicitouter)
+ // case pat if guard => body
+ case Alternative(trees) => (eliminated by transmatch/explicitouter)
+ // pat1 | ... | patn
+ case Star(elem) => (eliminated by transmatch/explicitouter)
+ // pat*
+ case Bind(name, body) => (eliminated by transmatch/explicitouter)
+ // name @ pat
+ case UnApply(fun: Tree, args) (introduced by typer, eliminated by transmatch/explicitouter)
+ // used for unapply's
+ case ArrayValue(elemtpt, trees) => (introduced by uncurry)
+ // used to pass arguments to vararg arguments
+ // for instance, printf("%s%d", foo, 42) is translated to after uncurry to:
+ // Apply(
+ // Ident("printf"),
+ // Literal("%s%d"),
+ // ArrayValue(<Any>, List(Ident("foo"), Literal(42))))
+ case Function(vparams, body) => (eliminated by lambdaLift)
+ // vparams => body where vparams:List[ValDef]
+ case Assign(lhs, rhs) =>
+ // lhs = rhs
+ case If(cond, thenp, elsep) =>
+ // if (cond) thenp else elsep
+ case Match(selector, cases) =>
+ // selector match { cases }
+ case Return(expr) =>
+ // return expr
+ case Try(block, catches, finalizer) =>
+ // try block catch { catches } finally finalizer where catches: List[CaseDef]
+ case Throw(expr) =>
+ // throw expr
+ case New(tpt) =>
+ // new tpt always in the context: (new tpt).<init>[targs](args)
+ case Typed(expr, tpt) => (eliminated by erasure)
+ // expr: tpt
+ case TypeApply(fun, args) =>
+ // fun[args]
+ case Apply(fun, args) =>
+ // fun(args)
+ // for instance fun[targs](args) is expressed as Apply(TypeApply(fun, targs), args)
+ case ApplyDynamic(qual, args) (introduced by erasure, eliminated by cleanup)
+ // fun(args)
+ case Super(qual, mix) =>
+ // qual.super[mix] if qual and/or mix is empty, ther are tpnme.EMPTY
+ case This(qual) =>
+ // qual.this
+ case Select(qualifier, selector) =>
+ // qualifier.selector
+ case Ident(name) =>
+ // name
+ // note: type checker converts idents that refer to enclosing fields or methods
+ // to selects; name ==> this.name
+ case Literal(value) =>
+ // value
+ case TypeTree() => (introduced by refcheck)
+ // a type that's not written out, but given in the tpe attribute
+ case Annotated(annot, arg) => (eliminated by typer)
+ // arg @annot for types, arg: @annot for exprs
+ case SingletonTypeTree(ref) => (eliminated by uncurry)
+ // ref.type
+ case SelectFromTypeTree(qualifier, selector) => (eliminated by uncurry)
+ // qualifier # selector, a path-dependent type p.T is expressed as p.type # T
+ case CompoundTypeTree(templ: Template) => (eliminated by uncurry)
+ // parent1 with ... with parentN { refinement }
+ case AppliedTypeTree(tpt, args) => (eliminated by uncurry)
+ // tpt[args]
+ case TypeBoundsTree(lo, hi) => (eliminated by uncurry)
+ // >: lo <: hi
+ case ExistentialTypeTree(tpt, whereClauses) => (eliminated by uncurry)
+ // tpt forSome { whereClauses }
+*/
+}
+
diff --git a/src/compiler/scala/reflect/api/Types.scala b/src/compiler/scala/reflect/api/Types.scala
new file mode 100755
index 0000000000..646c93ad5f
--- /dev/null
+++ b/src/compiler/scala/reflect/api/Types.scala
@@ -0,0 +1,124 @@
+package scala.reflect
+package api
+
+trait Types { self: Universe =>
+
+ abstract class AbsType {
+ def typeSymbol: Symbol
+ def decl(name: Name): Symbol
+ }
+
+ type Type >: Null <: AbsType
+ type SingletonType >: Null <: Type
+
+ val NoType: Type
+ val NoPrefix: Type
+
+ type ThisType <: SingletonType
+ val ThisType: ThisTypeExtractor
+
+ type TypeRef <: Type
+ val TypeRef: TypeRefExtractor
+
+ type SingleType <: SingletonType
+ val SingleType: SingleTypeExtractor
+
+ type SuperType <: SingletonType
+ val SuperType: SuperTypeExtractor
+
+ type TypeBounds <: Type
+ val TypeBounds: TypeBoundsExtractor
+
+ type CompoundType <: Type
+
+ type RefinedType <: CompoundType
+ val RefinedType: RefinedTypeExtractor
+
+ type ClassInfoType <: CompoundType
+ val ClassInfoType: ClassInfoTypeExtractor
+
+ type ConstantType <: Type
+ val ConstantType: ConstantTypeExtractor
+
+ type MethodType <: Type
+ val MethodType: MethodTypeExtractor
+
+ type NullaryMethodType <: Type
+ val NullaryMethodType: NullaryMethodTypeExtractor
+
+ type PolyType <: Type
+ val PolyType: PolyTypeExtractor
+
+ type ExistentialType <: Type
+ val ExistentialType: ExistentialTypeExtractor
+
+ type AnnotatedType <: Type
+ val AnnotatedType: AnnotatedTypeExtractor
+
+ abstract class ThisTypeExtractor {
+ def apply(sym: Symbol): Type
+ def unapply(tpe: ThisType): Option[Symbol]
+ }
+
+ abstract class SingleTypeExtractor {
+ def apply(pre: Type, sym: Symbol): Type
+ def unapply(tpe: SingleType): Option[(Type, Symbol)]
+ }
+
+ abstract class SuperTypeExtractor {
+ def apply(thistpe: Type, supertpe: Type): Type
+ def unapply(tpe: SuperType): Option[(Type, Type)]
+ }
+
+ abstract class TypeRefExtractor {
+ def apply(pre: Type, sym: Symbol, args: List[Type]): Type
+ def unapply(tpe: TypeRef): Option[(Type, Symbol, List[Type])]
+ }
+
+ abstract class TypeBoundsExtractor {
+ def apply(lo: Type, hi: Type): TypeBounds
+ def unapply(tpe: TypeBounds): Option[(Type, Type)]
+ }
+
+ abstract class RefinedTypeExtractor {
+ def apply(parents: List[Type], decls: Scope): RefinedType
+ def apply(parents: List[Type], decls: Scope, clazz: Symbol): RefinedType
+ def unapply(tpe: RefinedType): Option[(List[Type], Scope)]
+ }
+
+ abstract class ClassInfoTypeExtractor {
+ def apply(parents: List[Type], decls: Scope, clazz: Symbol): ClassInfoType
+ def unapply(tpe: ClassInfoType): Option[(List[Type], Scope, Symbol)]
+ }
+
+ abstract class ConstantTypeExtractor {
+ def apply(value: Constant): ConstantType
+ def unapply(tpe: ConstantType): Option[Constant]
+ }
+
+ abstract class MethodTypeExtractor {
+ def apply(params: List[Symbol], resultType: Type): MethodType
+ def unapply(tpe: MethodType): Option[(List[Symbol], Type)]
+ }
+
+ abstract class NullaryMethodTypeExtractor {
+ def apply(resultType: Type): NullaryMethodType
+ def unapply(tpe: NullaryMethodType): Option[(Type)]
+ }
+
+ abstract class PolyTypeExtractor {
+ def apply(typeParams: List[Symbol], resultType: Type): PolyType
+ def unapply(tpe: PolyType): Option[(List[Symbol], Type)]
+ }
+
+ abstract class ExistentialTypeExtractor {
+ def apply(quantified: List[Symbol], underlying: Type): ExistentialType
+ def unapply(tpe: ExistentialType): Option[(List[Symbol], Type)]
+ }
+
+ abstract class AnnotatedTypeExtractor {
+ def apply(annotations: List[AnnotationInfo], underlying: Type, selfsym: Symbol): AnnotatedType
+ def unapply(tpe: AnnotatedType): Option[(List[AnnotationInfo], Type, Symbol)]
+ }
+}
+
diff --git a/src/compiler/scala/reflect/api/Universe.scala b/src/compiler/scala/reflect/api/Universe.scala
new file mode 100755
index 0000000000..e0476c4e6d
--- /dev/null
+++ b/src/compiler/scala/reflect/api/Universe.scala
@@ -0,0 +1,16 @@
+package scala.reflect
+package api
+
+abstract class Universe extends Symbols
+ with Types
+ with Constants
+ with Scopes
+ with Names
+ with Trees
+ with Positions
+ with AnnotationInfos
+ with StandardDefinitions {
+ type Position
+ val NoPosition: Position
+}
+
diff --git a/src/compiler/scala/reflect/internal/AnnotationInfos.scala b/src/compiler/scala/reflect/internal/AnnotationInfos.scala
index 1da867a6b6..d49787d3df 100644
--- a/src/compiler/scala/reflect/internal/AnnotationInfos.scala
+++ b/src/compiler/scala/reflect/internal/AnnotationInfos.scala
@@ -9,7 +9,7 @@ package internal
import util._
/** AnnotationInfo and its helpers */
-trait AnnotationInfos /*extends reflect.generic.AnnotationInfos*/ { self: SymbolTable =>
+trait AnnotationInfos extends api.AnnotationInfos { self: SymbolTable =>
/** Arguments to classfile annotations (which are written to
* bytecode as java annotations) are either:
@@ -30,12 +30,16 @@ trait AnnotationInfos /*extends reflect.generic.AnnotationInfos*/ { self: Symbol
override def toString = const.escapedStringValue
}
+ object LiteralAnnotArg extends LiteralAnnotArgExtractor
+
/** Represents an array of classfile annotation arguments */
case class ArrayAnnotArg(args: Array[ClassfileAnnotArg])
extends ClassfileAnnotArg {
override def toString = args.mkString("[", ", ", "]")
}
+ object ArrayAnnotArg extends ArrayAnnotArgExtractor
+
/** A specific annotation argument that encodes an array of bytes as an array of `Long`. The type of the argument
* declared in the annotation must be `String`. This specialised class is used to encode scala signatures for
* reasons of efficiency, both in term of class-file size and in term of compiler performance. */
@@ -58,6 +62,8 @@ trait AnnotationInfos /*extends reflect.generic.AnnotationInfos*/ { self: Symbol
override def toString = annInfo.toString
}
+ object NestedAnnotArg extends NestedAnnotArgExtractor
+
class AnnotationInfoBase
/** <p>
@@ -131,6 +137,8 @@ trait AnnotationInfos /*extends reflect.generic.AnnotationInfos*/ { self: Symbol
} else None
}
+ object AnnotationInfo extends AnnotationInfoExtractor
+
lazy val classfileAnnotArgManifest: ClassManifest[ClassfileAnnotArg] =
reflect.ClassManifest.classType(classOf[ClassfileAnnotArg])
diff --git a/src/compiler/scala/reflect/internal/Constants.scala b/src/compiler/scala/reflect/internal/Constants.scala
index c4e2aceb7d..3299bee88a 100644
--- a/src/compiler/scala/reflect/internal/Constants.scala
+++ b/src/compiler/scala/reflect/internal/Constants.scala
@@ -9,7 +9,7 @@ package internal
import java.lang.Integer.toOctalString
import annotation.switch
-trait Constants {
+trait Constants extends api.Constants {
self: SymbolTable =>
import definitions._
@@ -30,7 +30,7 @@ trait Constants {
// For supporting java enumerations inside java annotations (see ClassfileParser)
final val EnumTag = 13
- case class Constant(value: Any) {
+ case class Constant(value: Any) extends AbsConstant {
val tag: Int = value match {
case null => NullTag
case x: Unit => UnitTag
@@ -235,4 +235,6 @@ trait Constants {
override def hashCode: Int = value.## * 41 + 17
}
+
+ object Constant extends ConstantExtractor
}
diff --git a/src/compiler/scala/reflect/internal/Definitions.scala b/src/compiler/scala/reflect/internal/Definitions.scala
index 9dd20cee95..6d9f8c28e9 100644
--- a/src/compiler/scala/reflect/internal/Definitions.scala
+++ b/src/compiler/scala/reflect/internal/Definitions.scala
@@ -11,7 +11,7 @@ import scala.collection.mutable.{ HashMap }
import Flags._
import PartialFunction._
-trait Definitions /*extends reflect.generic.StandardDefinitions*/ {
+trait Definitions extends reflect.api.StandardDefinitions {
self: SymbolTable =>
// the scala value classes
@@ -115,7 +115,7 @@ trait Definitions /*extends reflect.generic.StandardDefinitions*/ {
)
}
- object definitions extends ValueClassDefinitions {
+ object definitions extends AbsDefinitions with ValueClassDefinitions {
private var isInitialized = false
def isDefinitionsInitialized = isInitialized
diff --git a/src/compiler/scala/reflect/internal/Flags.scala b/src/compiler/scala/reflect/internal/Flags.scala
index 12dc5854db..f6cfb6680f 100644
--- a/src/compiler/scala/reflect/internal/Flags.scala
+++ b/src/compiler/scala/reflect/internal/Flags.scala
@@ -6,6 +6,8 @@
package scala.reflect
package internal
+import api.Modifier
+
// Flags at each index of a flags Long. Those marked with /M are used in
// Parsers/JavaParsers and therefore definitely appear on Modifiers; but the
// absence of /M on the other flags does not imply they aren't.
@@ -423,6 +425,35 @@ class Flags extends ModifierFlags {
front.toList ++ (all filterNot (front contains _))
}
+
+ def flagOfModifier(mod: Modifier.Value): Long = mod match {
+ case Modifier.`protected` => PROTECTED
+ case Modifier.`private` => PRIVATE
+ case Modifier.`override` => OVERRIDE
+ case Modifier.`abstract` => ABSTRACT
+ case Modifier.`final`=> FINAL
+ case Modifier.`sealed`=> SEALED
+ case Modifier.`implicit`=> IMPLICIT
+ case Modifier.`lazy`=> LAZY
+ case Modifier.`case`=> CASE
+ case Modifier.`trait`=> TRAIT
+ case Modifier.deferred => DEFERRED
+ case Modifier.interface => INTERFACE
+ case Modifier.mutable => MUTABLE
+ case Modifier.parameter => PARAM
+ case Modifier.covariant => COVARIANT
+ case Modifier.contravariant => CONTRAVARIANT
+ case Modifier.preSuper => PRESUPER
+ case Modifier.abstractOverride => ABSOVERRIDE
+ case Modifier.local => LOCAL
+ case Modifier.java => JAVA
+ case Modifier.static => STATIC
+ case Modifier.caseAccessor => CASEACCESSOR
+ case Modifier.defaultParameter => DEFAULTPARAM
+ case Modifier.defaultInit => DEFAULTINIT
+ case Modifier.paramAccessor => PARAMACCESSOR
+ case Modifier.bynameParameter => BYNAMEPARAM
+ }
}
object Flags extends Flags { }
diff --git a/src/compiler/scala/reflect/internal/Names.scala b/src/compiler/scala/reflect/internal/Names.scala
index 3ae15ebdec..4bfc0acfa2 100644
--- a/src/compiler/scala/reflect/internal/Names.scala
+++ b/src/compiler/scala/reflect/internal/Names.scala
@@ -15,7 +15,7 @@ import java.security.MessageDigest
* @author Martin Odersky
* @version 1.0, 05/02/2005
*/
-trait Names /*extends reflect.generic.Names*/ {
+trait Names extends api.Names {
// Operations -------------------------------------------------------------
@@ -105,22 +105,13 @@ trait Names /*extends reflect.generic.Names*/ {
def newTypeName(bs: Array[Byte], offset: Int, len: Int): TypeName =
newTermName(bs, offset, len).toTypeName
- def mkTermName(name: Name): TermName = name.toTermName
- def mkTypeName(name: Name): TypeName = name.toTypeName
- def isTermName(name: Name): Boolean = name.isTermName
- def isTypeName(name: Name): Boolean = name.isTypeName
-
def nameChars: Array[Char] = chrs
@deprecated("", "2.9.0") def view(s: String): TermName = newTermName(s)
- /** An implicit conversion from names to term names. */
- implicit def promoteTermNamesAsNecessary(name: Name): TermName = mkTermName(name)
-
-
// Classes ----------------------------------------------------------------------
/** The name class. */
- sealed abstract class Name(protected val index: Int, protected val len: Int) extends Function1[Int, Char] {
+ sealed abstract class Name(protected val index: Int, protected val len: Int) extends AbsName with Function1[Int, Char] {
/** Index into name table */
def start: Int = index
diff --git a/src/compiler/scala/reflect/internal/Positions.scala b/src/compiler/scala/reflect/internal/Positions.scala
index 75cbb80ab0..78de8d0ff2 100644
--- a/src/compiler/scala/reflect/internal/Positions.scala
+++ b/src/compiler/scala/reflect/internal/Positions.scala
@@ -1,10 +1,7 @@
package scala.reflect
package internal
-trait Positions { self: SymbolTable =>
-
- type Position
- val NoPosition: Position
+trait Positions extends api.Positions { self: SymbolTable =>
def focusPos(pos: Position): Position
def isRangePos(pos: Position): Boolean
diff --git a/src/compiler/scala/reflect/internal/Scopes.scala b/src/compiler/scala/reflect/internal/Scopes.scala
index 9f8eb025e5..c150abc7db 100644
--- a/src/compiler/scala/reflect/internal/Scopes.scala
+++ b/src/compiler/scala/reflect/internal/Scopes.scala
@@ -6,7 +6,7 @@
package scala.reflect
package internal
-trait Scopes { self: SymbolTable =>
+trait Scopes extends api.Scopes { self: SymbolTable =>
class ScopeEntry(val sym: Symbol, val owner: Scope) {
/** the next entry in the hash bucket
diff --git a/src/compiler/scala/reflect/internal/SymbolTable.scala b/src/compiler/scala/reflect/internal/SymbolTable.scala
index df73feaccc..68bf0082d2 100644
--- a/src/compiler/scala/reflect/internal/SymbolTable.scala
+++ b/src/compiler/scala/reflect/internal/SymbolTable.scala
@@ -9,8 +9,8 @@ package internal
import scala.collection.{ mutable, immutable }
import util._
-abstract class SymbolTable extends /*reflect.generic.Universe
- with*/ Names
+abstract class SymbolTable extends api.Universe
+ with Names
with Symbols
with Types
with Scopes
diff --git a/src/compiler/scala/reflect/internal/Symbols.scala b/src/compiler/scala/reflect/internal/Symbols.scala
index a900af6451..749368f93e 100644
--- a/src/compiler/scala/reflect/internal/Symbols.scala
+++ b/src/compiler/scala/reflect/internal/Symbols.scala
@@ -11,8 +11,9 @@ import scala.collection.{ mutable, immutable }
import scala.collection.mutable.ListBuffer
import util.Statistics._
import Flags._
+import api.Modifier
-trait Symbols /* extends reflect.generic.Symbols*/ { self: SymbolTable =>
+trait Symbols extends api.Symbols { self: SymbolTable =>
import definitions._
private var ids = 0
@@ -41,7 +42,7 @@ trait Symbols /* extends reflect.generic.Symbols*/ { self: SymbolTable =>
val originalOwner = perRunCaches.newMap[Symbol, Symbol]()
/** The class for all symbols */
- abstract class Symbol(initOwner: Symbol, initPos: Position, initName: Name) extends HasFlags /*AbsSymbol */ {
+ abstract class Symbol(initOwner: Symbol, initPos: Position, initName: Name) extends AbsSymbol with HasFlags {
type FlagsType = Long
type AccessBoundaryType = Symbol
@@ -59,6 +60,14 @@ trait Symbols /* extends reflect.generic.Symbols*/ { self: SymbolTable =>
def pos = rawpos
def setPos(pos: Position): this.type = { this.rawpos = pos; this }
+ override def hasModifier(mod: Modifier.Value) =
+ hasFlag(flagOfModifier(mod)) &&
+ (!(mod == Modifier.bynameParameter) || isTerm) &&
+ (!(mod == Modifier.covariant) || isType)
+
+ override def allModifiers: Set[Modifier.Value] =
+ Modifier.values filter hasModifier
+
// ------ creators -------------------------------------------------------------------
final def newValue(pos: Position, name: TermName) =
diff --git a/src/compiler/scala/reflect/internal/TreeInfo.scala b/src/compiler/scala/reflect/internal/TreeInfo.scala
index 44913699b4..abbe8390a6 100644
--- a/src/compiler/scala/reflect/internal/TreeInfo.scala
+++ b/src/compiler/scala/reflect/internal/TreeInfo.scala
@@ -15,10 +15,12 @@ import util.HashSet
* @version 1.0
*/
abstract class TreeInfo {
- val trees: SymbolTable
- import trees._
+ val global: SymbolTable
+ import global._
+
import definitions.ThrowableClass
+ /* Does not seem to be used. Not sure what it does anyway.
def isOwnerDefinition(tree: Tree): Boolean = tree match {
case PackageDef(_, _)
| ClassDef(_, _, _, _)
@@ -27,10 +29,13 @@ abstract class TreeInfo {
| Import(_, _) => true
case _ => false
}
+*/
- def isDefinition(tree: Tree): Boolean = tree.isDef
+ // def isDefinition(tree: Tree): Boolean = tree.isDef
- def isDeclaration(tree: Tree): Boolean = tree match {
+ /** Is tree a declaration or type definition?
+ */
+ def isDeclarationOrTypeDef(tree: Tree): Boolean = tree match {
case DefDef(_, _, _, _, _, EmptyTree)
| ValDef(_, _, _, EmptyTree)
| TypeDef(_, _, _, _) => true
@@ -45,7 +50,6 @@ abstract class TreeInfo {
case TypeDef(_, _, _, _) => true
case DefDef(mods, _, _, _, _, __) => mods.isDeferred
case ValDef(mods, _, _, _) => mods.isDeferred
- case DocDef(_, definition) => isInterfaceMember(definition)
case _ => false
}
@@ -60,8 +64,6 @@ abstract class TreeInfo {
true
case ValDef(mods, _, _, rhs) =>
!mods.isMutable && isPureExpr(rhs)
- case DocDef(_, definition) =>
- isPureDef(definition)
case _ =>
false
}
@@ -95,6 +97,8 @@ abstract class TreeInfo {
false
}
+ /** Is symbol potentially a getter of a variable?
+ */
def mayBeVarGetter(sym: Symbol): Boolean = sym.info match {
case NullaryMethodType(_) => sym.owner.isClass && !sym.isStable
case PolyType(_, NullaryMethodType(_)) => sym.owner.isClass && !sym.isStable
@@ -102,6 +106,8 @@ abstract class TreeInfo {
case _ => false
}
+ /** Is tree a mutable variable, or the getter of a mutable field?
+ */
def isVariableOrGetter(tree: Tree) = {
def sym = tree.symbol
def isVar = sym.isVariable
@@ -118,7 +124,8 @@ abstract class TreeInfo {
}
}
- /** Is tree a self constructor call?
+ /** Is tree a self constructor call this(...)? I.e. a call to a constructor of the
+ * same object?
*/
def isSelfConstrCall(tree: Tree): Boolean = methPart(tree) match {
case Ident(nme.CONSTRUCTOR)
@@ -126,15 +133,18 @@ abstract class TreeInfo {
case _ => false
}
+ /** Is tree a super constructor call?
+ */
def isSuperConstrCall(tree: Tree): Boolean = methPart(tree) match {
case Select(Super(_, _), nme.CONSTRUCTOR) => true
case _ => false
}
+ /** Is tree a self or super constructor call? */
def isSelfOrSuperConstrCall(tree: Tree) =
isSelfConstrCall(tree) || isSuperConstrCall(tree)
- /** Is tree a variable pattern */
+ /** Is tree a variable pattern? */
def isVarPattern(pat: Tree): Boolean = pat match {
case _: BackQuotedIdent => false
case x: Ident => isVariableName(x.name)
@@ -173,20 +183,22 @@ abstract class TreeInfo {
case _ => false
}
- /** Is tpt of the form T* ? */
+ /** Is tpt a vararg type of the form T* ? */
def isRepeatedParamType(tpt: Tree) = tpt match {
case TypeTree() => definitions.isRepeatedParamType(tpt.tpe)
case AppliedTypeTree(Select(_, tpnme.REPEATED_PARAM_CLASS_NAME), _) => true
case AppliedTypeTree(Select(_, tpnme.JAVA_REPEATED_PARAM_CLASS_NAME), _) => true
case _ => false
}
- /** The parameter ValDefs from a def of the form T*. */
+
+ /** The parameter ValDefs of a method definition that have vararg types of the form T*
+ */
def repeatedParams(tree: Tree): List[ValDef] = tree match {
case DefDef(_, _, _, vparamss, _, _) => vparamss.flatten filter (vd => isRepeatedParamType(vd.tpt))
case _ => Nil
}
- /** Is tpt a by-name parameter type? */
+ /** Is tpt a by-name parameter type of the form => T? */
def isByNameParamType(tpt: Tree) = tpt match {
case TypeTree() => definitions.isByNameParamType(tpt.tpe)
case AppliedTypeTree(Select(_, tpnme.BYNAME_PARAM_CLASS_NAME), _) => true
@@ -204,7 +216,7 @@ abstract class TreeInfo {
((first.isLower && first.isLetter) || first == '_') && !reserved(name)
}
- /** Is tree a this node which belongs to `enclClass`? */
+ /** Is tree a `this` node which belongs to `enclClass`? */
def isSelf(tree: Tree, enclClass: Symbol): Boolean = tree match {
case This(_) => tree.symbol == enclClass
case _ => false
@@ -225,10 +237,12 @@ abstract class TreeInfo {
case Typed(_, Ident(tpnme.WILDCARD_STAR)) => true
case _ => false
}
+
+ /** Does this argument list end with an argument of the form <expr> : _* ? */
def isWildcardStarArgList(trees: List[Tree]) =
trees.nonEmpty && isWildcardStarArg(trees.last)
- /** Is the argument a (possibly bound) _ arg?
+ /** Is the argument a wildcard argument of the form `_` or `x @ _`?
*/
def isWildcardArg(tree: Tree): Boolean = unbind(tree) match {
case Ident(nme.WILDCARD) => true
@@ -327,6 +341,18 @@ abstract class TreeInfo {
case _ => false
}
+ /** Does list of trees start with a definition of
+ * a class of module with given name (ignoring imports)
+ */
+ def firstDefinesClassOrObject(trees: List[Tree], name: Name): Boolean = trees match {
+ case Import(_, _) :: xs => firstDefinesClassOrObject(xs, name)
+ case Annotated(_, tree1) :: Nil => firstDefinesClassOrObject(List(tree1), name)
+ case ModuleDef(_, `name`, _) :: Nil => true
+ case ClassDef(_, `name`, _, _) :: Nil => true
+ case _ => false
+ }
+
+
/** Is this file the body of a compilation unit which should not
* have Predef imported?
*/
@@ -337,17 +363,10 @@ abstract class TreeInfo {
case Import(expr, _) :: rest => isPredefExpr(expr) || containsLeadingPredefImport(rest)
case _ => false
}
- def isImplDef(trees: List[Tree], name: Name): Boolean = trees match {
- case Import(_, _) :: xs => isImplDef(xs, name)
- case DocDef(_, tree1) :: Nil => isImplDef(List(tree1), name)
- case Annotated(_, tree1) :: Nil => isImplDef(List(tree1), name)
- case ModuleDef(_, `name`, _) :: Nil => true
- case ClassDef(_, `name`, _, _) :: Nil => true
- case _ => false
- }
+
// Compilation unit is class or object 'name' in package 'scala'
def isUnitInScala(tree: Tree, name: Name) = tree match {
- case PackageDef(Ident(nme.scala_), defs) => isImplDef(defs, name)
+ case PackageDef(Ident(nme.scala_), defs) => firstDefinesClassOrObject(defs, name)
case _ => false
}
diff --git a/src/compiler/scala/reflect/internal/TreePrinters.scala b/src/compiler/scala/reflect/internal/TreePrinters.scala
index 87096120f2..aef9219ed4 100644
--- a/src/compiler/scala/reflect/internal/TreePrinters.scala
+++ b/src/compiler/scala/reflect/internal/TreePrinters.scala
@@ -240,10 +240,7 @@ trait TreePrinters { self: SymbolTable =>
print(many.map(selectorToString).mkString("{", ", ", "}"))
}
- case DocDef(comment, definition) =>
- print(comment.raw); println(); print(definition)
-
- case Template(parents, self, body) =>
+ case Template(parents, self, body) =>
val currentOwner1 = currentOwner
if (tree.symbol != NoSymbol) currentOwner = tree.symbol.owner
printRow(parents, " with ")
@@ -303,9 +300,6 @@ trait TreePrinters { self: SymbolTable =>
case Assign(lhs, rhs) =>
print(lhs); print(" = "); print(rhs)
- case AssignOrNamedArg(lhs, rhs) =>
- print(lhs); print(" = "); print(rhs)
-
case If(cond, thenp, elsep) =>
print("if ("); print(cond); print(")"); indent; println()
print(thenp); undent
@@ -406,14 +400,15 @@ trait TreePrinters { self: SymbolTable =>
print(tpt);
printColumn(whereClauses, " forSome { ", ";", "}")
- case SelectFromArray(qualifier, name, _) =>
- print(qualifier); print(".<arr>"); print(symName(tree, name))
+// SelectFromArray is no longer visible in reflect.internal.
+// eliminated until we figure out what we will do with both TreePrinters and
+// SelectFromArray.
+// case SelectFromArray(qualifier, name, _) =>
+// print(qualifier); print(".<arr>"); print(symName(tree, name))
- case TypeTreeWithDeferredRefCheck() =>
- print("<tree with deferred refcheck>")
case tree =>
- print("<unknown tree of class "+tree.getClass+">")
+ xprintRaw(this, tree)
}
if (settings.printtypes.value && tree.isTerm && !tree.isEmpty) {
print("{"); print(if (tree.tpe eq null) "<null>" else tree.tpe.toString()); print("}")
@@ -440,6 +435,8 @@ trait TreePrinters { self: SymbolTable =>
}
}
+ def xprintRaw(treePrinter: TreePrinter, tree: Tree) = print("<unknown tree of class "+tree.getClass+">")
+
def newTreePrinter(writer: PrintWriter): TreePrinter = new TreePrinter(writer)
def newTreePrinter(stream: OutputStream): TreePrinter = newTreePrinter(new PrintWriter(stream))
def newTreePrinter(): TreePrinter = newTreePrinter(new PrintWriter(ConsoleWriter))
diff --git a/src/compiler/scala/reflect/internal/Trees.scala b/src/compiler/scala/reflect/internal/Trees.scala
index 5480d90c5a..d9b9e10601 100644
--- a/src/compiler/scala/reflect/internal/Trees.scala
+++ b/src/compiler/scala/reflect/internal/Trees.scala
@@ -6,23 +6,16 @@
package scala.reflect
package internal
+import java.io.{PrintWriter, StringWriter}
import scala.collection.mutable.ListBuffer
import Flags._
-import util.HashSet
-import java.io.{ PrintWriter, StringWriter }
-import Flags._
+import api.Modifier
//import scala.tools.nsc.util.{ FreshNameCreator, HashSet, SourceFile }
-trait Trees /*extends reflect.generic.Trees*/ { self: SymbolTable =>
-
- type DocComment <: { def raw: String }
-
- private[scala] var nodeCount = 0
+trait Trees extends api.Trees { self: SymbolTable =>
- object treeInfo extends {
- val trees: Trees.this.type = self
- } with TreeInfo
+ // --- modifiers implementation ---------------------------------------
/** @param privateWithin the qualifier for a private (a type name)
* or tpnme.EMPTY, if none is given.
@@ -30,7 +23,11 @@ trait Trees /*extends reflect.generic.Trees*/ { self: SymbolTable =>
* '''Note:''' the typechecker drops these annotations,
* use the AnnotationInfo's (Symbol.annotations) in later phases.
*/
- case class Modifiers(flags: Long, privateWithin: Name, annotations: List[Tree], positions: Map[Long, Position]) extends HasFlags {
+ case class Modifiers(flags: Long,
+ privateWithin: Name,
+ annotations: List[Tree],
+ positions: Map[Long, Position]) extends AbsModifiers with HasFlags {
+
/* Abstract types from HasFlags. */
type FlagsType = Long
type AccessBoundaryType = Name
@@ -64,553 +61,62 @@ trait Trees /*extends reflect.generic.Trees*/ { self: SymbolTable =>
def withPosition(flag: Long, position: Position) =
copy(positions = positions + (flag -> position))
+ override def hasModifier(mod: Modifier.Value) =
+ hasFlag(flagOfModifier(mod))
+ override def allModifiers: Set[Modifier.Value] =
+ Modifier.values filter hasModifier
+ override def mapAnnotations(f: List[Tree] => List[Tree]): Modifiers =
+ Modifiers(flags, privateWithin, f(annotations), positions)
+
override def toString = "Modifiers(%s, %s, %s)".format(hasFlagsToString(-1L), annotations mkString ", ", positions)
}
def Modifiers(flags: Long, privateWithin: Name): Modifiers = Modifiers(flags, privateWithin, List(), Map.empty)
def Modifiers(flags: Long): Modifiers = Modifiers(flags, tpnme.EMPTY)
- lazy val NoMods = Modifiers(0)
-
- // ------ tree base classes --------------------------------------------------
-
- /** The base class for all trees */
- abstract class Tree extends Product {
- val id = nodeCount
- nodeCount += 1
-
- private[this] var rawpos: Position = NoPosition
-
- def pos = rawpos
- def pos_=(pos: Position) = rawpos = pos
- def setPos(pos: Position): this.type = { rawpos = pos; this }
-
- private[this] var rawtpe: Type = _
-
- def tpe = rawtpe
- def tpe_=(t: Type) = rawtpe = t
-
- /** Set tpe to give `tp` and return this.
- */
- def setType(tp: Type): this.type = { rawtpe = tp; this }
-
- /** Like `setType`, but if this is a previously empty TypeTree
- * that fact is remembered so that resetType will snap back.
- */
- def defineType(tp: Type): this.type = setType(tp)
-
- def symbol: Symbol = null
- def symbol_=(sym: Symbol) { throw new UnsupportedOperationException("symbol_= inapplicable for " + this) }
- def setSymbol(sym: Symbol): this.type = { symbol = sym; this }
-
- def hasSymbol = false
- def isDef = false
- def isEmpty = false
+ def Modifiers(mods: Set[Modifier.Value],
+ privateWithin: Name,
+ annotations: List[Tree]): Modifiers = {
+ val flagSet = mods map flagOfModifier
+ Modifiers((0L /: flagSet)(_ | _), privateWithin, annotations, Map.empty)
+ }
- def hasSymbolWhich(f: Symbol => Boolean) = hasSymbol && f(symbol)
+ lazy val NoMods = Modifiers(0)
- def isTerm: Boolean = this match {
- case _: TermTree => true
- case Bind(name, _) => name.isTermName
- case Select(_, name) => name.isTermName
- case Ident(name) => name.isTermName
- case Annotated(_, arg) => arg.isTerm
- case DocDef(_, defn) => defn.isTerm
- case _ => false
- }
+ // --- extension methods --------------------------------------------------------
- def isType: Boolean = this match {
- case _: TypTree => true
- case Bind(name, _) => name.isTypeName
- case Select(_, name) => name.isTypeName
- case Ident(name) => name.isTypeName
- case Annotated(_, arg) => arg.isType
- case DocDef(_, defn) => defn.isType
- case _ => false
- }
+ override def show(tree: Tree): String = {
+ val buffer = new StringWriter()
+ val printer = newTreePrinter(new PrintWriter(buffer))
+ printer.print(tree)
+ printer.flush()
+ buffer.toString
+ }
- def isErroneous = (this.tpe ne null) && this.tpe.isErroneous
- def isTyped = (this.tpe ne null) && !this.tpe.isErroneous
+ implicit def treeOps(tree: Tree): TreeOps = new TreeOps(tree)
- /** Apply `f` to each subtree */
- def foreach(f: Tree => Unit) { new ForeachTreeTraverser(f).traverse(this) }
+ class TreeOps(tree: Tree) {
+ def isErroneous = (tree.tpe ne null) && tree.tpe.isErroneous
+ def isTyped = (tree.tpe ne null) && !tree.tpe.isErroneous
/** If `pf` is defined for a given subtree, call super.traverse(pf(tree)),
* otherwise super.traverse(tree).
*/
- def foreachPartial(pf: PartialFunction[Tree, Tree]) { new ForeachPartialTreeTraverser(pf).traverse(this) }
-
- /** Find all subtrees matching predicate `p` */
- def filter(f: Tree => Boolean): List[Tree] = {
- val ft = new FilterTreeTraverser(f)
- ft.traverse(this)
- ft.hits.toList
- }
-
- /** Returns optionally first tree (in a preorder traversal) which satisfies predicate `p`,
- * or None if none exists.
- */
- def find(p: Tree => Boolean): Option[Tree] = {
- val ft = new FindTreeTraverser(p)
- ft.traverse(this)
- ft.result
+ def foreachPartial(pf: PartialFunction[Tree, Tree]) {
+ new ForeachPartialTreeTraverser(pf).traverse(tree)
}
def changeOwner(pairs: (Symbol, Symbol)*): Tree = {
- pairs.foldLeft(this) { case (t, (oldOwner, newOwner)) =>
+ pairs.foldLeft(tree) { case (t, (oldOwner, newOwner)) =>
new ChangeOwnerTraverser(oldOwner, newOwner) apply t
}
}
- /** Is there part of this tree which satisfies predicate `p`? */
- def exists(p: Tree => Boolean): Boolean = !find(p).isEmpty
-
- def equalsStructure(that : Tree) = equalsStructure0(that)(_ eq _)
- def equalsStructure0(that: Tree)(f: (Tree,Tree) => Boolean): Boolean =
- f(this, that) || ((this.productArity == that.productArity) && {
- def equals0(this0: Any, that0: Any): Boolean = (this0, that0) match {
- case (x: Tree, y: Tree) => f(x, y) || (x equalsStructure0 y)(f)
- case (xs: List[_], ys: List[_]) => (xs corresponds ys)(equals0)
- case _ => this0 == that0
- }
- def compareOriginals() = (this, that) match {
- case (x: TypeTree, y: TypeTree) if x.original != null && y.original != null =>
- (x.original equalsStructure0 y.original)(f)
- case _ =>
- true
- }
-
- (this.productIterator zip that.productIterator forall { case (x, y) => equals0(x, y) }) && compareOriginals()
- })
-
- def shallowDuplicate: Tree = new ShallowDuplicator(this) transform this
+ def shallowDuplicate: Tree = new ShallowDuplicator(tree) transform tree
def shortClass: String = this.getClass.getName split "[.$]" last
- /** The direct child trees of this tree
- * EmptyTrees are always omitted. Lists are collapsed.
- */
- def children: List[Tree] = {
- def subtrees(x: Any): List[Tree] = x match {
- case EmptyTree => Nil
- case t: Tree => List(t)
- case xs: List[_] => xs flatMap subtrees
- case _ => Nil
- }
- productIterator.toList flatMap subtrees
- }
-
- /** Make a copy of this tree, keeping all attributes,
- * except that all positions are focused (so nothing
- * in this tree will be found when searching by position).
- */
- private[scala] def duplicate: this.type =
- duplicateTree(this).asInstanceOf[this.type]
-
- private[scala] def copyAttrs(tree: Tree): this.type = {
- pos = tree.pos
- tpe = tree.tpe
- if (hasSymbol) symbol = tree.symbol
- this
- }
-
- override def toString(): String = {
- val buffer = new StringWriter()
- val printer = newTreePrinter(new PrintWriter(buffer))
- printer.print(this)
- printer.flush()
- buffer.toString
- }
-
- override def hashCode(): Int = System.identityHashCode(this)
- override def equals(that: Any) = this eq that.asInstanceOf[AnyRef]
- }
-
- trait SymTree extends Tree {
- override def hasSymbol = true
- override var symbol: Symbol = NoSymbol
- }
-
- trait RefTree extends SymTree {
- def name: Name
- }
-
- abstract class DefTree extends SymTree {
- def name: Name
- override def isDef = true
- }
-
- trait TermTree extends Tree
-
- /** A tree for a type. Note that not all type trees implement
- * this trait; in particular, Ident's are an exception. */
- trait TypTree extends Tree
-
-// ----- tree node alternatives --------------------------------------
-
- /** The empty tree */
- case object EmptyTree extends TermTree {
- super.tpe_=(NoType)
- override def tpe_=(t: Type) =
- if (t != NoType) throw new UnsupportedOperationException("tpe_=("+t+") inapplicable for <empty>")
- override def isEmpty = true
- }
-
- abstract class MemberDef extends DefTree {
- def mods: Modifiers
- def keyword: String = this match {
- case TypeDef(_, _, _, _) => "type"
- case ClassDef(mods, _, _, _) => if (mods hasFlag TRAIT) "trait" else "class"
- case DefDef(_, _, _, _, _, _) => "def"
- case ModuleDef(_, _, _) => "object"
- case PackageDef(_, _) => "package"
- case ValDef(mods, _, _, _) => if (mods.isMutable) "var" else "val"
- case _ => ""
- }
- // final def hasFlag(mask: Long): Boolean = mods hasFlag mask
- }
-
- /** Package clause
- */
- case class PackageDef(pid: RefTree, stats: List[Tree])
- extends MemberDef {
- def name = pid.name
- def mods = NoMods
- }
-
- abstract class ImplDef extends MemberDef {
- def impl: Template
- }
-
- /** Class definition */
- case class ClassDef(mods: Modifiers, name: TypeName, tparams: List[TypeDef], impl: Template)
- extends ImplDef
-
- /** Singleton object definition
- */
- case class ModuleDef(mods: Modifiers, name: TermName, impl: Template)
- extends ImplDef
-
- abstract class ValOrDefDef extends MemberDef {
- def name: TermName
- def tpt: Tree
- def rhs: Tree
- }
-
- /** Value definition
- */
- case class ValDef(mods: Modifiers, name: TermName, tpt: Tree, rhs: Tree) extends ValOrDefDef
-
- /** Method definition
- */
- case class DefDef(mods: Modifiers, name: TermName, tparams: List[TypeDef],
- vparamss: List[List[ValDef]], tpt: Tree, rhs: Tree) extends ValOrDefDef
-
- /** Abstract type, type parameter, or type alias */
- case class TypeDef(mods: Modifiers, name: TypeName, tparams: List[TypeDef], rhs: Tree)
- extends MemberDef
-
- /** <p>
- * Labelled expression - the symbols in the array (must be Idents!)
- * are those the label takes as argument
- * </p>
- * <p>
- * The symbol that is given to the labeldef should have a MethodType
- * (as if it were a nested function)
- * </p>
- * <p>
- * Jumps are apply nodes attributed with label symbol, the arguments
- * will get assigned to the idents.
- * </p>
- * <p>
- * Note: on 2005-06-09 Martin, Iuli, Burak agreed to have forward
- * jumps within a Block.
- * </p>
- */
- case class LabelDef(name: TermName, params: List[Ident], rhs: Tree)
- extends DefTree with TermTree
-
-
- /** Import selector
- *
- * Representation of an imported name its optional rename and their optional positions
- *
- * @param name the imported name
- * @param namePos its position or -1 if undefined
- * @param rename the name the import is renamed to (== name if no renaming)
- * @param renamePos the position of the rename or -1 if undefined
- */
- case class ImportSelector(name: Name, namePos: Int, rename: Name, renamePos: Int)
-
- /** Import clause
- *
- * @param expr
- * @param selectors
- */
- case class Import(expr: Tree, selectors: List[ImportSelector])
- extends SymTree
- // The symbol of an Import is an import symbol @see Symbol.newImport
- // It's used primarily as a marker to check that the import has been typechecked.
-
- /** Instantiation template of a class or trait
- *
- * @param parents
- * @param body
- */
- case class Template(parents: List[Tree], self: ValDef, body: List[Tree])
- extends SymTree {
- // the symbol of a template is a local dummy. @see Symbol.newLocalDummy
- // the owner of the local dummy is the enclosing trait or class.
- // the local dummy is itself the owner of any local blocks
- // For example:
- //
- // class C {
- // def foo // owner is C
- // {
- // def bar // owner is local dummy
- // }
- // System.err.println("TEMPLATE: " + parents)
- }
-
- /** Block of expressions (semicolon separated expressions) */
- case class Block(stats: List[Tree], expr: Tree)
- extends TermTree
-
- /** Case clause in a pattern match, eliminated during explicitouter
- * (except for occurrences in switch statements)
- */
- case class CaseDef(pat: Tree, guard: Tree, body: Tree)
- extends Tree
-
- /** Alternatives of patterns, eliminated by explicitouter, except for
- * occurrences in encoded Switch stmt (=remaining Match(CaseDef(...))
- */
- case class Alternative(trees: List[Tree])
- extends TermTree
-
- /** Repetition of pattern, eliminated by explicitouter */
- case class Star(elem: Tree)
- extends TermTree
-
- /** Bind of a variable to a rhs pattern, eliminated by explicitouter
- *
- * @param name
- * @param body
- */
- case class Bind(name: Name, body: Tree)
- extends DefTree
-
- case class UnApply(fun: Tree, args: List[Tree])
- extends TermTree
-
- /** Array of expressions, needs to be translated in backend,
- */
- case class ArrayValue(elemtpt: Tree, elems: List[Tree])
- extends TermTree
-
- /** Anonymous function, eliminated by analyzer */
- case class Function(vparams: List[ValDef], body: Tree)
- extends TermTree with SymTree
- // The symbol of a Function is a synthetic value of name nme.ANON_FUN_NAME
- // It is the owner of the function's parameters.
-
- /** Assignment */
- case class Assign(lhs: Tree, rhs: Tree)
- extends TermTree
-
- /** Conditional expression */
- case class If(cond: Tree, thenp: Tree, elsep: Tree)
- extends TermTree
-
- /** <p>
- * Pattern matching expression (before explicitouter)
- * Switch statements (after explicitouter)
- * </p>
- * <p>
- * After explicitouter, cases will satisfy the following constraints:
- * </p>
- * <ul>
- * <li>all guards are EmptyTree,</li>
- * <li>all patterns will be either <code>Literal(Constant(x:Int))</code>
- * or <code>Alternative(lit|...|lit)</code></li>
- * <li>except for an "otherwise" branch, which has pattern
- * <code>Ident(nme.WILDCARD)</code></li>
- * </ul>
- */
- case class Match(selector: Tree, cases: List[CaseDef])
- extends TermTree
-
- /** Return expression */
- case class Return(expr: Tree)
- extends TermTree with SymTree
- // The symbol of a Return node is the enclosing method.
-
- case class Try(block: Tree, catches: List[CaseDef], finalizer: Tree)
- extends TermTree
-
- /** Throw expression */
- case class Throw(expr: Tree)
- extends TermTree
-
- /** Object instantiation
- * One should always use factory method below to build a user level new.
- *
- * @param tpt a class type
- */
- case class New(tpt: Tree) extends TermTree
-
- /** Type annotation, eliminated by explicit outer */
- case class Typed(expr: Tree, tpt: Tree)
- extends TermTree
-
- // Martin to Sean: Should GenericApply/TypeApply/Apply not be SymTree's? After all,
- // ApplyDynamic is a SymTree.
- abstract class GenericApply extends TermTree {
- val fun: Tree
- val args: List[Tree]
- }
-
- /** Type application */
- case class TypeApply(fun: Tree, args: List[Tree])
- extends GenericApply {
- override def symbol: Symbol = fun.symbol
- override def symbol_=(sym: Symbol) { fun.symbol = sym }
- }
-
- /** Value application */
- case class Apply(fun: Tree, args: List[Tree])
- extends GenericApply {
- override def symbol: Symbol = fun.symbol
- override def symbol_=(sym: Symbol) { fun.symbol = sym }
- }
-
- /** Dynamic value application.
- * In a dynamic application q.f(as)
- * - q is stored in qual
- * - as is stored in args
- * - f is stored as the node's symbol field.
- */
- case class ApplyDynamic(qual: Tree, args: List[Tree])
- extends TermTree with SymTree
- // The symbol of an ApplyDynamic is the function symbol of `qual`, or NoSymbol, if there is none.
-
- /** Super reference, qual = corresponding this reference */
- case class Super(qual: Tree, mix: TypeName) extends TermTree {
- // The symbol of a Super is the class _from_ which the super reference is made.
- // For instance in C.super(...), it would be C.
- override def symbol: Symbol = qual.symbol
- override def symbol_=(sym: Symbol) { qual.symbol = sym }
- }
-
- /** Self reference */
- case class This(qual: TypeName)
- extends TermTree with SymTree
- // The symbol of a This is the class to which the this refers.
- // For instance in C.this, it would be C.
-
- /** Designator <qualifier> . <name> */
- case class Select(qualifier: Tree, name: Name)
- extends RefTree
-
- /** Identifier <name> */
- case class Ident(name: Name) extends RefTree { }
-
- class BackQuotedIdent(name: Name) extends Ident(name)
-
- /** Literal */
- case class Literal(value: Constant)
- extends TermTree {
- assert(value ne null)
- }
-
- def Literal(value: Any): Literal =
- Literal(Constant(value))
-
- /** A tree that has an annotation attached to it. Only used for annotated types and
- * annotation ascriptions, annotations on definitions are stored in the Modifiers.
- * Eliminated by typechecker (typedAnnotated), the annotations are then stored in
- * an AnnotatedType.
- */
- case class Annotated(annot: Tree, arg: Tree) extends Tree
-
- /** Singleton type, eliminated by RefCheck */
- case class SingletonTypeTree(ref: Tree)
- extends TypTree
-
- /** Type selection <qualifier> # <name>, eliminated by RefCheck */
- case class SelectFromTypeTree(qualifier: Tree, name: TypeName)
- extends TypTree with RefTree
-
- /** Intersection type <parent1> with ... with <parentN> { <decls> }, eliminated by RefCheck */
- case class CompoundTypeTree(templ: Template)
- extends TypTree
-
- /** Applied type <tpt> [ <args> ], eliminated by RefCheck */
- case class AppliedTypeTree(tpt: Tree, args: List[Tree])
- extends TypTree {
- override def symbol: Symbol = tpt.symbol
- override def symbol_=(sym: Symbol) { tpt.symbol = sym }
}
- case class TypeBoundsTree(lo: Tree, hi: Tree)
- extends TypTree
-
- case class ExistentialTypeTree(tpt: Tree, whereClauses: List[Tree])
- extends TypTree
-
- /** Array selection <qualifier> . <name> only used during erasure */
- case class SelectFromArray(qualifier: Tree, name: Name, erasure: Type)
- extends TermTree with RefTree { }
-
- /** A synthetic tree holding an arbitrary type. Not to be confused with
- * with TypTree, the trait for trees that are only used for type trees.
- * TypeTree's are inserted in several places, but most notably in
- * `RefCheck`, where the arbitrary type trees are all replaced by
- * TypeTree's. */
- case class TypeTree() extends TypTree {
- private var orig: Tree = null
- private[Trees] var wasEmpty: Boolean = false
-
- override def symbol = if (tpe == null) null else tpe.typeSymbol
- override def isEmpty = (tpe eq null) || tpe == NoType
-
- def original: Tree = orig
- def setOriginal(tree: Tree): this.type = {
- def followOriginal(t: Tree): Tree = t match {
- case tt: TypeTree => followOriginal(tt.original)
- case t => t
- }
-
- orig = followOriginal(tree); setPos(tree.pos);
- this
- }
-
- override def defineType(tp: Type): this.type = {
- wasEmpty = isEmpty
- setType(tp)
- }
- }
-
- def TypeTree(tp: Type): TypeTree = TypeTree() setType tp
-
- /** Documented definition, eliminated by analyzer */
- case class DocDef(comment: DocComment, definition: Tree)
- extends Tree {
- override def symbol: Symbol = definition.symbol
- override def symbol_=(sym: Symbol) { definition.symbol = sym }
- // sean: seems to be important to the IDE
- override def isDef = definition.isDef
- }
-
- /** Either an assignment or a named argument. Only appears in argument lists,
- * eliminated by typecheck (doTypedApply)
- */
- case class AssignOrNamedArg(lhs: Tree, rhs: Tree)
- extends TermTree
-
- case class Parens(args: List[Tree]) extends Tree // only used during parsing
-
- /** emitted by typer, eliminated by refchecks */
- case class TypeTreeWithDeferredRefCheck()(val check: () => TypeTree) extends TypTree
// ---- values and creators ---------------------------------------
/** @param sym the class symbol
@@ -624,23 +130,6 @@ trait Trees /*extends reflect.generic.Trees*/ { self: SymbolTable =>
impl) setSymbol sym
}
- /** Construct class definition with given class symbol, value parameters,
- * supercall arguments and template body.
- *
- * @param sym the class symbol
- * @param constrMods the modifiers for the class constructor, i.e. as in `class C private (...)`
- * @param vparamss the value parameters -- if they have symbols they
- * should be owned by `sym`
- * @param argss the supercall arguments
- * @param body the template statements without primary constructor
- * and value parameter fields.
- */
- def ClassDef(sym: Symbol, constrMods: Modifiers, vparamss: List[List[ValDef]], argss: List[List[Tree]], body: List[Tree], superPos: Position): ClassDef =
- ClassDef(sym,
- Template(sym.info.parents map TypeTree,
- if (sym.thisSym == sym || phase.erasedTypes) emptyValDef else ValDef(sym.thisSym),
- constrMods, vparamss, argss, body, superPos))
-
/**
* @param sym the class symbol
* @param impl the implementation template
@@ -704,73 +193,6 @@ trait Trees /*extends reflect.generic.Trees*/ { self: SymbolTable =>
LabelDef(sym.name, params map Ident, rhs) setSymbol sym
}
- /** Generates a template with constructor corresponding to
- *
- * constrmods (vparams1_) ... (vparams_n) preSuper { presupers }
- * extends superclass(args_1) ... (args_n) with mixins { self => body }
- *
- * This gets translated to
- *
- * extends superclass with mixins { self =>
- * presupers' // presupers without rhs
- * vparamss // abstract fields corresponding to value parameters
- * def <init>(vparamss) {
- * presupers
- * super.<init>(args)
- * }
- * body
- * }
- */
- def Template(parents: List[Tree], self: ValDef, constrMods: Modifiers, vparamss: List[List[ValDef]], argss: List[List[Tree]], body: List[Tree], superPos: Position): Template = {
- /* Add constructor to template */
-
- // create parameters for <init> as synthetic trees.
- var vparamss1 =
- vparamss map (vps => vps.map { vd =>
- atPos(focusPos(vd.pos)) {
- ValDef(
- Modifiers(vd.mods.flags & (IMPLICIT | DEFAULTPARAM | BYNAMEPARAM) | PARAM | PARAMACCESSOR) withAnnotations vd.mods.annotations,
- vd.name, vd.tpt.duplicate, vd.rhs.duplicate)
- }})
- val (edefs, rest) = body span treeInfo.isEarlyDef
- val (evdefs, etdefs) = edefs partition treeInfo.isEarlyValDef
- val (lvdefs, gvdefs) = evdefs map {
- case vdef @ ValDef(mods, name, tpt, rhs) =>
- val fld = treeCopy.ValDef(
- vdef.duplicate, mods, name,
- atPos(focusPos(vdef.pos)) { TypeTree() setOriginal tpt setPos focusPos(tpt.pos) }, // atPos in case
- EmptyTree)
- val local = treeCopy.ValDef(vdef, Modifiers(PRESUPER), name, tpt, rhs)
- (local, fld)
- } unzip
-
- val constrs = {
- if (constrMods hasFlag TRAIT) {
- if (body forall treeInfo.isInterfaceMember) List()
- else List(
- atPos(wrappingPos(superPos, lvdefs)) (
- DefDef(NoMods, nme.MIXIN_CONSTRUCTOR, List(), List(List()), TypeTree(), Block(lvdefs, Literal(())))))
- } else {
- // convert (implicit ... ) to ()(implicit ... ) if its the only parameter section
- if (vparamss1.isEmpty || !vparamss1.head.isEmpty && vparamss1.head.head.mods.isImplicit)
- vparamss1 = List() :: vparamss1;
- val superRef: Tree = atPos(superPos) {
- Select(Super(This(tpnme.EMPTY), tpnme.EMPTY), nme.CONSTRUCTOR)
- }
- val superCall = (superRef /: argss) (Apply)
- List(
- atPos(wrappingPos(superPos, lvdefs ::: argss.flatten)) (
- DefDef(constrMods, nme.CONSTRUCTOR, List(), vparamss1, TypeTree(), Block(lvdefs ::: List(superCall), Literal(())))))
- }
- }
- // println("typed template, gvdefs = "+gvdefs+", parents = "+parents+", constrs = "+constrs)
- constrs foreach (ensureNonOverlapping(_, parents ::: gvdefs))
- // vparamss2 are used as field definitions for the class. remove defaults
- val vparamss2 = vparamss map (vps => vps map { vd =>
- treeCopy.ValDef(vd, vd.mods &~ DEFAULTPARAM, vd.name, vd.tpt, EmptyTree)
- })
- Template(parents, self, gvdefs ::: vparamss2.flatten ::: constrs ::: etdefs ::: rest)
- }
/** casedef shorthand */
def CaseDef(pat: Tree, body: Tree): CaseDef = CaseDef(pat, EmptyTree, body)
@@ -809,700 +231,56 @@ trait Trees /*extends reflect.generic.Trees*/ { self: SymbolTable =>
case Seq(_, rest @ _*) => Block(stats.init.toList, stats.last)
}
-// ----- subconstructors --------------------------------------------
-
- class ApplyToImplicitArgs(fun: Tree, args: List[Tree]) extends Apply(fun, args)
-
- class ApplyImplicitView(fun: Tree, args: List[Tree]) extends Apply(fun, args)
-
-// ------ traversers, copiers, and transformers ---------------------------------------------
+ // --- specific traversers and transformers
- val treeCopy = new LazyTreeCopier()
-
- class Traverser {
- protected var currentOwner: Symbol = definitions.RootClass
- def traverse(tree: Tree): Unit = tree match {
- case EmptyTree =>
- ;
- case PackageDef(pid, stats) =>
- traverse(pid)
- atOwner(tree.symbol.moduleClass) {
- traverseTrees(stats)
- }
- case ClassDef(mods, name, tparams, impl) =>
- atOwner(tree.symbol) {
- traverseTrees(mods.annotations); traverseTrees(tparams); traverse(impl)
- }
- case ModuleDef(mods, name, impl) =>
- atOwner(tree.symbol.moduleClass) {
- traverseTrees(mods.annotations); traverse(impl)
- }
- case ValDef(mods, name, tpt, rhs) =>
- atOwner(tree.symbol) {
- traverseTrees(mods.annotations); traverse(tpt); traverse(rhs)
- }
- case DefDef(mods, name, tparams, vparamss, tpt, rhs) =>
- atOwner(tree.symbol) {
- traverseTrees(mods.annotations); traverseTrees(tparams); traverseTreess(vparamss); traverse(tpt); traverse(rhs)
- }
- case TypeDef(mods, name, tparams, rhs) =>
- atOwner(tree.symbol) {
- traverseTrees(mods.annotations); traverseTrees(tparams); traverse(rhs)
- }
- case LabelDef(name, params, rhs) =>
- traverseTrees(params); traverse(rhs)
- case Import(expr, selectors) =>
- traverse(expr)
- case Annotated(annot, arg) =>
- traverse(annot); traverse(arg)
- case Template(parents, self, body) =>
- traverseTrees(parents)
- if (!self.isEmpty) traverse(self)
- traverseStats(body, tree.symbol)
- case Block(stats, expr) =>
- traverseTrees(stats); traverse(expr)
- case CaseDef(pat, guard, body) =>
- traverse(pat); traverse(guard); traverse(body)
- case Alternative(trees) =>
- traverseTrees(trees)
- case Star(elem) =>
- traverse(elem)
- case Bind(name, body) =>
- traverse(body)
- case UnApply(fun, args) =>
- traverse(fun); traverseTrees(args)
- case ArrayValue(elemtpt, trees) =>
- traverse(elemtpt); traverseTrees(trees)
- case Function(vparams, body) =>
- atOwner(tree.symbol) {
- traverseTrees(vparams); traverse(body)
- }
- case Assign(lhs, rhs) =>
- traverse(lhs); traverse(rhs)
- case If(cond, thenp, elsep) =>
- traverse(cond); traverse(thenp); traverse(elsep)
- case Match(selector, cases) =>
- traverse(selector); traverseTrees(cases)
- case Return(expr) =>
- traverse(expr)
- case Try(block, catches, finalizer) =>
- traverse(block); traverseTrees(catches); traverse(finalizer)
- case Throw(expr) =>
- traverse(expr)
- case New(tpt) =>
- traverse(tpt)
- case Typed(expr, tpt) =>
- traverse(expr); traverse(tpt)
- case TypeApply(fun, args) =>
- traverse(fun); traverseTrees(args)
- case Apply(fun, args) =>
- traverse(fun); traverseTrees(args)
- case ApplyDynamic(qual, args) =>
- traverse(qual); traverseTrees(args)
- case Super(qual, _) =>
- traverse(qual)
- case This(_) =>
- ;
- case Select(qualifier, selector) =>
- traverse(qualifier)
- case Ident(_) =>
- ;
- case Literal(_) =>
- ;
- case TypeTree() =>
- ;
- case SingletonTypeTree(ref) =>
- traverse(ref)
- case SelectFromTypeTree(qualifier, selector) =>
- traverse(qualifier)
- case CompoundTypeTree(templ) =>
- traverse(templ)
- case AppliedTypeTree(tpt, args) =>
- traverse(tpt); traverseTrees(args)
- case TypeBoundsTree(lo, hi) =>
- traverse(lo); traverse(hi)
- case ExistentialTypeTree(tpt, whereClauses) =>
- traverse(tpt); traverseTrees(whereClauses)
- case SelectFromArray(qualifier, selector, erasure) =>
- traverse(qualifier)
- case AssignOrNamedArg(lhs, rhs) =>
- traverse(lhs); traverse(rhs)
- case DocDef(comment, definition) =>
- traverse(definition)
- case Parens(ts) =>
- traverseTrees(ts)
- 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)
- }
+ protected[scala] def duplicateTree(tree: Tree): Tree = duplicator transform tree
- def traverseTrees(trees: List[Tree]) {
- trees foreach traverse
- }
- def traverseTreess(treess: List[List[Tree]]) {
- treess foreach traverseTrees
- }
- def traverseStats(stats: List[Tree], exprOwner: Symbol) {
- stats foreach (stat =>
- if (exprOwner != currentOwner) atOwner(exprOwner)(traverse(stat))
- else traverse(stat)
- )
- }
-
- def atOwner(owner: Symbol)(traverse: => Unit) {
- val prevOwner = currentOwner
- currentOwner = owner
- traverse
- currentOwner = prevOwner
+ private lazy val duplicator = new Transformer {
+ override val treeCopy = newStrictTreeCopier
+ override def transform(t: Tree) = {
+ val t1 = super.transform(t)
+ if ((t1 ne t) && isRangePos(t1.pos)) t1 setPos focusPos(t.pos)
+ t1
}
-
- /** Leave apply available in the generic traverser to do something else.
- */
- def apply[T <: Tree](tree: T): T = { traverse(tree); tree }
}
- abstract class TreeCopier {
- def ClassDef(tree: Tree, mods: Modifiers, name: Name, tparams: List[TypeDef], impl: Template): ClassDef
- def PackageDef(tree: Tree, pid: RefTree, stats: List[Tree]): PackageDef
- def ModuleDef(tree: Tree, mods: Modifiers, name: Name, impl: Template): ModuleDef
- def ValDef(tree: Tree, mods: Modifiers, name: Name, tpt: Tree, rhs: Tree): ValDef
- def DefDef(tree: Tree, mods: Modifiers, name: Name, tparams: List[TypeDef], vparamss: List[List[ValDef]], tpt: Tree, rhs: Tree): DefDef
- def TypeDef(tree: Tree, mods: Modifiers, name: Name, tparams: List[TypeDef], rhs: Tree): TypeDef
- def LabelDef(tree: Tree, name: Name, params: List[Ident], rhs: Tree): LabelDef
- def Import(tree: Tree, expr: Tree, selectors: List[ImportSelector]): Import
- def DocDef(tree: Tree, comment: DocComment, definition: Tree): DocDef
- def Template(tree: Tree, parents: List[Tree], self: ValDef, body: List[Tree]): Template
- def Block(tree: Tree, stats: List[Tree], expr: Tree): Block
- def CaseDef(tree: Tree, pat: Tree, guard: Tree, body: Tree): CaseDef
- def Alternative(tree: Tree, trees: List[Tree]): Alternative
- def Star(tree: Tree, elem: Tree): Star
- def Bind(tree: Tree, name: Name, body: Tree): Bind
- def UnApply(tree: Tree, fun: Tree, args: List[Tree]): UnApply
- def ArrayValue(tree: Tree, elemtpt: Tree, trees: List[Tree]): ArrayValue
- def Function(tree: Tree, vparams: List[ValDef], body: Tree): Function
- def Assign(tree: Tree, lhs: Tree, rhs: Tree): Assign
- def AssignOrNamedArg(tree: Tree, lhs: Tree, rhs: Tree): AssignOrNamedArg
- def If(tree: Tree, cond: Tree, thenp: Tree, elsep: Tree): If
- def Match(tree: Tree, selector: Tree, cases: List[CaseDef]): Match
- def Return(tree: Tree, expr: Tree): Return
- def Try(tree: Tree, block: Tree, catches: List[CaseDef], finalizer: Tree): Try
- def Throw(tree: Tree, expr: Tree): Throw
- def New(tree: Tree, tpt: Tree): New
- def Typed(tree: Tree, expr: Tree, tpt: Tree): Typed
- def TypeApply(tree: Tree, fun: Tree, args: List[Tree]): TypeApply
- def Apply(tree: Tree, fun: Tree, args: List[Tree]): Apply
- def ApplyDynamic(tree: Tree, qual: Tree, args: List[Tree]): ApplyDynamic
- def Super(tree: Tree, qual: Tree, mix: TypeName): Super
- def This(tree: Tree, qual: Name): This
- def Select(tree: Tree, qualifier: Tree, selector: Name): Select
- def Ident(tree: Tree, name: Name): Ident
- def Literal(tree: Tree, value: Constant): Literal
- def TypeTree(tree: Tree): TypeTree
- def TypeTreeWithDeferredRefCheck(tree: Tree): TypeTreeWithDeferredRefCheck
- def Annotated(tree: Tree, annot: Tree, arg: Tree): Annotated
- def SingletonTypeTree(tree: Tree, ref: Tree): SingletonTypeTree
- def SelectFromTypeTree(tree: Tree, qualifier: Tree, selector: Name): SelectFromTypeTree
- def CompoundTypeTree(tree: Tree, templ: Template): CompoundTypeTree
- def AppliedTypeTree(tree: Tree, tpt: Tree, args: List[Tree]): AppliedTypeTree
- def TypeBoundsTree(tree: Tree, lo: Tree, hi: Tree): TypeBoundsTree
- def ExistentialTypeTree(tree: Tree, tpt: Tree, whereClauses: List[Tree]): ExistentialTypeTree
- def SelectFromArray(tree: Tree, qualifier: Tree, selector: Name, erasure: Type): SelectFromArray
- }
-
- class StrictTreeCopier extends TreeCopier {
- def ClassDef(tree: Tree, mods: Modifiers, name: Name, tparams: List[TypeDef], impl: Template) =
- new ClassDef(mods, name.toTypeName, tparams, impl).copyAttrs(tree)
- def PackageDef(tree: Tree, pid: RefTree, stats: List[Tree]) =
- new PackageDef(pid, stats).copyAttrs(tree)
- def ModuleDef(tree: Tree, mods: Modifiers, name: Name, impl: Template) =
- new ModuleDef(mods, name, impl).copyAttrs(tree)
- def ValDef(tree: Tree, mods: Modifiers, name: Name, tpt: Tree, rhs: Tree) =
- new ValDef(mods, name, tpt, rhs).copyAttrs(tree)
- def DefDef(tree: Tree, mods: Modifiers, name: Name, tparams: List[TypeDef], vparamss: List[List[ValDef]], tpt: Tree, rhs: Tree) =
- new DefDef(mods, name, tparams, vparamss, tpt, rhs).copyAttrs(tree)
- def TypeDef(tree: Tree, mods: Modifiers, name: Name, tparams: List[TypeDef], rhs: Tree) =
- new TypeDef(mods, name.toTypeName, tparams, rhs).copyAttrs(tree)
- def LabelDef(tree: Tree, name: Name, params: List[Ident], rhs: Tree) =
- new LabelDef(name, params, rhs).copyAttrs(tree)
- def Import(tree: Tree, expr: Tree, selectors: List[ImportSelector]) =
- new Import(expr, selectors).copyAttrs(tree)
- def DocDef(tree: Tree, comment: DocComment, definition: Tree) =
- new DocDef(comment, definition).copyAttrs(tree)
- def Template(tree: Tree, parents: List[Tree], self: ValDef, body: List[Tree]) =
- new Template(parents, self, body).copyAttrs(tree)
- def Block(tree: Tree, stats: List[Tree], expr: Tree) =
- new Block(stats, expr).copyAttrs(tree)
- def CaseDef(tree: Tree, pat: Tree, guard: Tree, body: Tree) =
- new CaseDef(pat, guard, body).copyAttrs(tree)
- def Alternative(tree: Tree, trees: List[Tree]) =
- new Alternative(trees).copyAttrs(tree)
- def Star(tree: Tree, elem: Tree) =
- new Star(elem).copyAttrs(tree)
- def Bind(tree: Tree, name: Name, body: Tree) =
- new Bind(name, body).copyAttrs(tree)
- def UnApply(tree: Tree, fun: Tree, args: List[Tree]) =
- new UnApply(fun, args).copyAttrs(tree)
- def ArrayValue(tree: Tree, elemtpt: Tree, trees: List[Tree]) =
- new ArrayValue(elemtpt, trees).copyAttrs(tree)
- def Function(tree: Tree, vparams: List[ValDef], body: Tree) =
- new Function(vparams, body).copyAttrs(tree)
- def Assign(tree: Tree, lhs: Tree, rhs: Tree) =
- new Assign(lhs, rhs).copyAttrs(tree)
- def AssignOrNamedArg(tree: Tree, lhs: Tree, rhs: Tree) =
- new AssignOrNamedArg(lhs, rhs).copyAttrs(tree)
- def If(tree: Tree, cond: Tree, thenp: Tree, elsep: Tree) =
- new If(cond, thenp, elsep).copyAttrs(tree)
- def Match(tree: Tree, selector: Tree, cases: List[CaseDef]) =
- new Match(selector, cases).copyAttrs(tree)
- def Return(tree: Tree, expr: Tree) =
- new Return(expr).copyAttrs(tree)
- def Try(tree: Tree, block: Tree, catches: List[CaseDef], finalizer: Tree) =
- new Try(block, catches, finalizer).copyAttrs(tree)
- def Throw(tree: Tree, expr: Tree) =
- new Throw(expr).copyAttrs(tree)
- def New(tree: Tree, tpt: Tree) =
- new New(tpt).copyAttrs(tree)
- def Typed(tree: Tree, expr: Tree, tpt: Tree) =
- new Typed(expr, tpt).copyAttrs(tree)
- def TypeApply(tree: Tree, fun: Tree, args: List[Tree]) =
- new TypeApply(fun, args).copyAttrs(tree)
- def Apply(tree: Tree, fun: Tree, args: List[Tree]) =
- (tree match {
- case _: ApplyToImplicitArgs => new ApplyToImplicitArgs(fun, args)
- case _: ApplyImplicitView => new ApplyImplicitView(fun, args)
- case _ => new Apply(fun, args)
- }).copyAttrs(tree)
- def ApplyDynamic(tree: Tree, qual: Tree, args: List[Tree]) =
- new ApplyDynamic(qual, args).copyAttrs(tree)
- def Super(tree: Tree, qual: Tree, mix: TypeName) =
- new Super(qual, mix).copyAttrs(tree)
- def This(tree: Tree, qual: Name) =
- new This(qual.toTypeName).copyAttrs(tree)
- def Select(tree: Tree, qualifier: Tree, selector: Name) =
- new Select(qualifier, selector).copyAttrs(tree)
- def Ident(tree: Tree, name: Name) =
- new Ident(name).copyAttrs(tree)
- def Literal(tree: Tree, value: Constant) =
- new Literal(value).copyAttrs(tree)
- def TypeTree(tree: Tree) =
- new TypeTree().copyAttrs(tree)
- def TypeTreeWithDeferredRefCheck(tree: Tree) = tree match {
- case dc@TypeTreeWithDeferredRefCheck() => new TypeTreeWithDeferredRefCheck()(dc.check).copyAttrs(tree)
+ private object posAssigner extends Traverser {
+ var pos: Position = _
+ override def traverse(t: Tree) {
+ if (t != EmptyTree && t.pos == NoPosition) {
+ t.setPos(pos)
+ super.traverse(t)
+ }
}
- def Annotated(tree: Tree, annot: Tree, arg: Tree) =
- new Annotated(annot, arg).copyAttrs(tree)
- def SingletonTypeTree(tree: Tree, ref: Tree) =
- new SingletonTypeTree(ref).copyAttrs(tree)
- def SelectFromTypeTree(tree: Tree, qualifier: Tree, selector: Name) =
- new SelectFromTypeTree(qualifier, selector.toTypeName).copyAttrs(tree)
- def CompoundTypeTree(tree: Tree, templ: Template) =
- new CompoundTypeTree(templ).copyAttrs(tree)
- def AppliedTypeTree(tree: Tree, tpt: Tree, args: List[Tree]) =
- new AppliedTypeTree(tpt, args).copyAttrs(tree)
- def TypeBoundsTree(tree: Tree, lo: Tree, hi: Tree) =
- new TypeBoundsTree(lo, hi).copyAttrs(tree)
- def ExistentialTypeTree(tree: Tree, tpt: Tree, whereClauses: List[Tree]) =
- new ExistentialTypeTree(tpt, whereClauses).copyAttrs(tree)
- def SelectFromArray(tree: Tree, qualifier: Tree, selector: Name, erasure: Type) =
- new SelectFromArray(qualifier, selector, erasure).copyAttrs(tree)
}
- class LazyTreeCopier(treeCopy: TreeCopier) extends TreeCopier {
- def this() = this(new StrictTreeCopier)
- def ClassDef(tree: Tree, mods: Modifiers, name: Name, tparams: List[TypeDef], impl: Template) = tree match {
- case t @ ClassDef(mods0, name0, tparams0, impl0)
- if (mods0 == mods) && (name0 == name) && (tparams0 == tparams) && (impl0 == impl) => t
- case _ => treeCopy.ClassDef(tree, mods, name, tparams, impl)
- }
- def PackageDef(tree: Tree, pid: RefTree, stats: List[Tree]) = tree match {
- case t @ PackageDef(pid0, stats0)
- if (pid0 == pid) && (stats0 == stats) => t
- case _ => treeCopy.PackageDef(tree, pid, stats)
- }
- def ModuleDef(tree: Tree, mods: Modifiers, name: Name, impl: Template) = tree match {
- case t @ ModuleDef(mods0, name0, impl0)
- if (mods0 == mods) && (name0 == name) && (impl0 == impl) => t
- case _ => treeCopy.ModuleDef(tree, mods, name, impl)
- }
- def ValDef(tree: Tree, mods: Modifiers, name: Name, tpt: Tree, rhs: Tree) = tree match {
- case t @ ValDef(mods0, name0, tpt0, rhs0)
- if (mods0 == mods) && (name0 == name) && (tpt0 == tpt) && (rhs0 == rhs) => t
- case _ => treeCopy.ValDef(tree, mods, name, tpt, rhs)
- }
- def DefDef(tree: Tree, mods: Modifiers, name: Name, tparams: List[TypeDef], vparamss: List[List[ValDef]], tpt: Tree, rhs: Tree) = tree match {
- case t @ DefDef(mods0, name0, tparams0, vparamss0, tpt0, rhs0)
- if (mods0 == mods) && (name0 == name) && (tparams0 == tparams) &&
- (vparamss0 == vparamss) && (tpt0 == tpt) && (rhs == rhs0) => t
- case _ => treeCopy.DefDef(tree, mods, name, tparams, vparamss, tpt, rhs)
- }
- def TypeDef(tree: Tree, mods: Modifiers, name: Name, tparams: List[TypeDef], rhs: Tree) = tree match {
- case t @ TypeDef(mods0, name0, tparams0, rhs0)
- if (mods0 == mods) && (name0 == name) && (tparams0 == tparams) && (rhs0 == rhs) => t
- case _ => treeCopy.TypeDef(tree, mods, name, tparams, rhs)
- }
- def LabelDef(tree: Tree, name: Name, params: List[Ident], rhs: Tree) = tree match {
- case t @ LabelDef(name0, params0, rhs0)
- if (name0 == name) && (params0 == params) && (rhs0 == rhs) => t
- case _ => treeCopy.LabelDef(tree, name, params, rhs)
- }
- def Import(tree: Tree, expr: Tree, selectors: List[ImportSelector]) = tree match {
- case t @ Import(expr0, selectors0)
- if (expr0 == expr) && (selectors0 == selectors) => t
- case _ => treeCopy.Import(tree, expr, selectors)
- }
- def DocDef(tree: Tree, comment: DocComment, definition: Tree) = tree match {
- case t @ DocDef(comment0, definition0)
- if (comment0 == comment) && (definition0 == definition) => t
- case _ => treeCopy.DocDef(tree, comment, definition)
- }
- def Template(tree: Tree, parents: List[Tree], self: ValDef, body: List[Tree]) = tree match {
- case t @ Template(parents0, self0, body0)
- if (parents0 == parents) && (self0 == self) && (body0 == body) => t
- case _ => treeCopy.Template(tree, parents, self, body)
- }
- def Block(tree: Tree, stats: List[Tree], expr: Tree) = tree match {
- case t @ Block(stats0, expr0)
- if ((stats0 == stats) && (expr0 == expr)) => t
- case _ => treeCopy.Block(tree, stats, expr)
- }
- def CaseDef(tree: Tree, pat: Tree, guard: Tree, body: Tree) = tree match {
- case t @ CaseDef(pat0, guard0, body0)
- if (pat0 == pat) && (guard0 == guard) && (body0 == body) => t
- case _ => treeCopy.CaseDef(tree, pat, guard, body)
- }
- def Alternative(tree: Tree, trees: List[Tree]) = tree match {
- case t @ Alternative(trees0)
- if trees0 == trees => t
- case _ => treeCopy.Alternative(tree, trees)
- }
- def Star(tree: Tree, elem: Tree) = tree match {
- case t @ Star(elem0)
- if elem0 == elem => t
- case _ => treeCopy.Star(tree, elem)
- }
- def Bind(tree: Tree, name: Name, body: Tree) = tree match {
- case t @ Bind(name0, body0)
- if (name0 == name) && (body0 == body) => t
- case _ => treeCopy.Bind(tree, name, body)
- }
- def UnApply(tree: Tree, fun: Tree, args: List[Tree]) = tree match {
- case t @ UnApply(fun0, args0)
- if (fun0 == fun) && (args0 == args) => t
- case _ => treeCopy.UnApply(tree, fun, args)
- }
- def ArrayValue(tree: Tree, elemtpt: Tree, trees: List[Tree]) = tree match {
- case t @ ArrayValue(elemtpt0, trees0)
- if (elemtpt0 == elemtpt) && (trees0 == trees) => t
- case _ => treeCopy.ArrayValue(tree, elemtpt, trees)
- }
- def Function(tree: Tree, vparams: List[ValDef], body: Tree) = tree match {
- case t @ Function(vparams0, body0)
- if (vparams0 == vparams) && (body0 == body) => t
- case _ => treeCopy.Function(tree, vparams, body)
- }
- def Assign(tree: Tree, lhs: Tree, rhs: Tree) = tree match {
- case t @ Assign(lhs0, rhs0)
- if (lhs0 == lhs) && (rhs0 == rhs) => t
- case _ => treeCopy.Assign(tree, lhs, rhs)
- }
- def AssignOrNamedArg(tree: Tree, lhs: Tree, rhs: Tree) = tree match {
- case t @ AssignOrNamedArg(lhs0, rhs0)
- if (lhs0 == lhs) && (rhs0 == rhs) => t
- case _ => treeCopy.AssignOrNamedArg(tree, lhs, rhs)
- }
- def If(tree: Tree, cond: Tree, thenp: Tree, elsep: Tree) = tree match {
- case t @ If(cond0, thenp0, elsep0)
- if (cond0 == cond) && (thenp0 == thenp) && (elsep0 == elsep) => t
- case _ => treeCopy.If(tree, cond, thenp, elsep)
- }
- def Match(tree: Tree, selector: Tree, cases: List[CaseDef]) = tree match {
- case t @ Match(selector0, cases0)
- if (selector0 == selector) && (cases0 == cases) => t
- case _ => treeCopy.Match(tree, selector, cases)
- }
- def Return(tree: Tree, expr: Tree) = tree match {
- case t @ Return(expr0)
- if expr0 == expr => t
- case _ => treeCopy.Return(tree, expr)
- }
- def Try(tree: Tree, block: Tree, catches: List[CaseDef], finalizer: Tree) = tree match {
- case t @ Try(block0, catches0, finalizer0)
- if (block0 == block) && (catches0 == catches) && (finalizer0 == finalizer) => t
- case _ => treeCopy.Try(tree, block, catches, finalizer)
- }
- def Throw(tree: Tree, expr: Tree) = tree match {
- case t @ Throw(expr0)
- if expr0 == expr => t
- case _ => treeCopy.Throw(tree, expr)
- }
- def New(tree: Tree, tpt: Tree) = tree match {
- case t @ New(tpt0)
- if tpt0 == tpt => t
- case _ => treeCopy.New(tree, tpt)
- }
- def Typed(tree: Tree, expr: Tree, tpt: Tree) = tree match {
- case t @ Typed(expr0, tpt0)
- if (expr0 == expr) && (tpt0 == tpt) => t
- case _ => treeCopy.Typed(tree, expr, tpt)
- }
- def TypeApply(tree: Tree, fun: Tree, args: List[Tree]) = tree match {
- case t @ TypeApply(fun0, args0)
- if (fun0 == fun) && (args0 == args) => t
- case _ => treeCopy.TypeApply(tree, fun, args)
- }
- def Apply(tree: Tree, fun: Tree, args: List[Tree]) = tree match {
- case t @ Apply(fun0, args0)
- if (fun0 == fun) && (args0 == args) => t
- case _ => treeCopy.Apply(tree, fun, args)
- }
- def ApplyDynamic(tree: Tree, qual: Tree, args: List[Tree]) = tree match {
- case t @ ApplyDynamic(qual0, args0)
- if (qual0 == qual) && (args0 == args) => t
- case _ => treeCopy.ApplyDynamic(tree, qual, args)
- }
- def Super(tree: Tree, qual: Tree, mix: TypeName) = tree match {
- case t @ Super(qual0, mix0)
- if (qual0 == qual) && (mix0 == mix) => t
- case _ => treeCopy.Super(tree, qual, mix)
- }
- def This(tree: Tree, qual: Name) = tree match {
- case t @ This(qual0)
- if qual0 == qual => t
- case _ => treeCopy.This(tree, qual)
- }
- def Select(tree: Tree, qualifier: Tree, selector: Name) = tree match {
- case t @ Select(qualifier0, selector0)
- if (qualifier0 == qualifier) && (selector0 == selector) => t
- case _ => treeCopy.Select(tree, qualifier, selector)
- }
- def Ident(tree: Tree, name: Name) = tree match {
- case t @ Ident(name0)
- if name0 == name => t
- case _ => treeCopy.Ident(tree, name)
- }
- def Literal(tree: Tree, value: Constant) = tree match {
- case t @ Literal(value0)
- if value0 == value => t
- case _ => treeCopy.Literal(tree, value)
- }
- def TypeTree(tree: Tree) = tree match {
- case t @ TypeTree() => t
- case _ => treeCopy.TypeTree(tree)
- }
- def TypeTreeWithDeferredRefCheck(tree: Tree) = tree match {
- case t @ TypeTreeWithDeferredRefCheck() => t
- case _ => treeCopy.TypeTreeWithDeferredRefCheck(tree)
- }
- def Annotated(tree: Tree, annot: Tree, arg: Tree) = tree match {
- case t @ Annotated(annot0, arg0)
- if (annot0==annot) => t
- case _ => treeCopy.Annotated(tree, annot, arg)
- }
- def SingletonTypeTree(tree: Tree, ref: Tree) = tree match {
- case t @ SingletonTypeTree(ref0)
- if ref0 == ref => t
- case _ => treeCopy.SingletonTypeTree(tree, ref)
- }
- def SelectFromTypeTree(tree: Tree, qualifier: Tree, selector: Name) = tree match {
- case t @ SelectFromTypeTree(qualifier0, selector0)
- if (qualifier0 == qualifier) && (selector0 == selector) => t
- case _ => treeCopy.SelectFromTypeTree(tree, qualifier, selector)
- }
- def CompoundTypeTree(tree: Tree, templ: Template) = tree match {
- case t @ CompoundTypeTree(templ0)
- if templ0 == templ => t
- case _ => treeCopy.CompoundTypeTree(tree, templ)
- }
- def AppliedTypeTree(tree: Tree, tpt: Tree, args: List[Tree]) = tree match {
- case t @ AppliedTypeTree(tpt0, args0)
- if (tpt0 == tpt) && (args0 == args) => t
- case _ => treeCopy.AppliedTypeTree(tree, tpt, args)
- }
- def TypeBoundsTree(tree: Tree, lo: Tree, hi: Tree) = tree match {
- case t @ TypeBoundsTree(lo0, hi0)
- if (lo0 == lo) && (hi0 == hi) => t
- case _ => treeCopy.TypeBoundsTree(tree, lo, hi)
- }
- def ExistentialTypeTree(tree: Tree, tpt: Tree, whereClauses: List[Tree]) = tree match {
- case t @ ExistentialTypeTree(tpt0, whereClauses0)
- if (tpt0 == tpt) && (whereClauses0 == whereClauses) => t
- case _ => treeCopy.ExistentialTypeTree(tree, tpt, whereClauses)
- }
- def SelectFromArray(tree: Tree, qualifier: Tree, selector: Name, erasure: Type) = tree match {
- case t @ SelectFromArray(qualifier0, selector0, _)
- if (qualifier0 == qualifier) && (selector0 == selector) => t
- case _ => treeCopy.SelectFromArray(tree, qualifier, selector, erasure)
- }
+ def atPos[T <: Tree](pos: Position)(tree: T): T = {
+ posAssigner.pos = pos
+ posAssigner.traverse(tree)
+ tree
}
- abstract class Transformer {
- val treeCopy: TreeCopier = new LazyTreeCopier
- protected var currentOwner: Symbol = definitions.RootClass
- protected def currentMethod = currentOwner.enclMethod
- protected def currentClass = currentOwner.enclClass
- protected def currentPackage = currentOwner.toplevelClass.owner
- def transform(tree: Tree): Tree = tree match {
- case EmptyTree =>
- tree
- case PackageDef(pid, stats) =>
- treeCopy.PackageDef(
- tree, transform(pid).asInstanceOf[RefTree],
- atOwner(tree.symbol.moduleClass) {
- transformStats(stats, currentOwner)
- }
- )
- case ClassDef(mods, name, tparams, impl) =>
- atOwner(tree.symbol) {
- treeCopy.ClassDef(tree, transformModifiers(mods), name,
- transformTypeDefs(tparams), transformTemplate(impl))
- }
- case ModuleDef(mods, name, impl) =>
- atOwner(tree.symbol.moduleClass) {
- treeCopy.ModuleDef(tree, transformModifiers(mods),
- name, transformTemplate(impl))
- }
- case ValDef(mods, name, tpt, rhs) =>
- atOwner(tree.symbol) {
- treeCopy.ValDef(tree, transformModifiers(mods),
- name, transform(tpt), transform(rhs))
- }
- case DefDef(mods, name, tparams, vparamss, tpt, rhs) =>
- atOwner(tree.symbol) {
- treeCopy.DefDef(tree, transformModifiers(mods), name,
- transformTypeDefs(tparams), transformValDefss(vparamss),
- transform(tpt), transform(rhs))
- }
- case TypeDef(mods, name, tparams, rhs) =>
- atOwner(tree.symbol) {
- treeCopy.TypeDef(tree, transformModifiers(mods), name,
- transformTypeDefs(tparams), transform(rhs))
- }
- case LabelDef(name, params, rhs) =>
- treeCopy.LabelDef(tree, name, transformIdents(params), transform(rhs)) //bq: Martin, once, atOwner(...) works, also change `LamdaLifter.proxy'
- case Import(expr, selectors) =>
- treeCopy.Import(tree, transform(expr), selectors)
- case DocDef(comment, definition) =>
- treeCopy.DocDef(tree, comment, transform(definition))
- case Template(parents, self, body) =>
- treeCopy.Template(tree, transformTrees(parents), transformValDef(self), transformStats(body, tree.symbol))
- case Block(stats, expr) =>
- treeCopy.Block(tree, transformStats(stats, currentOwner), transform(expr))
- case CaseDef(pat, guard, body) =>
- treeCopy.CaseDef(tree, transform(pat), transform(guard), transform(body))
- case Alternative(trees) =>
- treeCopy.Alternative(tree, transformTrees(trees))
- case Star(elem) =>
- treeCopy.Star(tree, transform(elem))
- case Bind(name, body) =>
- treeCopy.Bind(tree, name, transform(body))
- case UnApply(fun, args) =>
- treeCopy.UnApply(tree, fun, transformTrees(args)) // bq: see test/.../unapplyContexts2.scala
- case ArrayValue(elemtpt, trees) =>
- treeCopy.ArrayValue(tree, transform(elemtpt), transformTrees(trees))
- case Function(vparams, body) =>
- atOwner(tree.symbol) {
- treeCopy.Function(tree, transformValDefs(vparams), transform(body))
- }
- case Assign(lhs, rhs) =>
- treeCopy.Assign(tree, transform(lhs), transform(rhs))
- case AssignOrNamedArg(lhs, rhs) =>
- treeCopy.AssignOrNamedArg(tree, transform(lhs), transform(rhs))
- case If(cond, thenp, elsep) =>
- treeCopy.If(tree, transform(cond), transform(thenp), transform(elsep))
- case Match(selector, cases) =>
- treeCopy.Match(tree, transform(selector), transformCaseDefs(cases))
- case Return(expr) =>
- treeCopy.Return(tree, transform(expr))
- case Try(block, catches, finalizer) =>
- treeCopy.Try(tree, transform(block), transformCaseDefs(catches), transform(finalizer))
- case Throw(expr) =>
- treeCopy.Throw(tree, transform(expr))
- case New(tpt) =>
- treeCopy.New(tree, transform(tpt))
- case Typed(expr, tpt) =>
- treeCopy.Typed(tree, transform(expr), transform(tpt))
- case TypeApply(fun, args) =>
- treeCopy.TypeApply(tree, transform(fun), transformTrees(args))
- case Apply(fun, args) =>
- treeCopy.Apply(tree, transform(fun), transformTrees(args))
- case ApplyDynamic(qual, args) =>
- treeCopy.ApplyDynamic(tree, transform(qual), transformTrees(args))
- case Super(qual, mix) =>
- treeCopy.Super(tree, transform(qual), mix)
- case This(qual) =>
- treeCopy.This(tree, qual)
- case Select(qualifier, selector) =>
- treeCopy.Select(tree, transform(qualifier), selector)
- case Ident(name) =>
- treeCopy.Ident(tree, name)
- case Literal(value) =>
- treeCopy.Literal(tree, value)
- case TypeTree() =>
- treeCopy.TypeTree(tree)
- case TypeTreeWithDeferredRefCheck() =>
- treeCopy.TypeTreeWithDeferredRefCheck(tree)
- case Annotated(annot, arg) =>
- treeCopy.Annotated(tree, transform(annot), transform(arg))
- case SingletonTypeTree(ref) =>
- treeCopy.SingletonTypeTree(tree, transform(ref))
- case SelectFromTypeTree(qualifier, selector) =>
- treeCopy.SelectFromTypeTree(tree, transform(qualifier), selector)
- case CompoundTypeTree(templ) =>
- treeCopy.CompoundTypeTree(tree, transformTemplate(templ))
- case AppliedTypeTree(tpt, args) =>
- treeCopy.AppliedTypeTree(tree, transform(tpt), transformTrees(args))
- case TypeBoundsTree(lo, hi) =>
- treeCopy.TypeBoundsTree(tree, transform(lo), transform(hi))
- case ExistentialTypeTree(tpt, whereClauses) =>
- treeCopy.ExistentialTypeTree(tree, transform(tpt), transformTrees(whereClauses))
- case SelectFromArray(qualifier, selector, erasure) =>
- treeCopy.SelectFromArray(tree, transform(qualifier), selector, erasure)
- }
-
- def transformTrees(trees: List[Tree]): List[Tree] =
- trees mapConserve (transform(_))
- def transformTemplate(tree: Template): Template =
- transform(tree: Tree).asInstanceOf[Template]
- def transformTypeDefs(trees: List[TypeDef]): List[TypeDef] =
- trees mapConserve (tree => transform(tree).asInstanceOf[TypeDef])
- def transformValDef(tree: ValDef): ValDef =
- if (tree.isEmpty) tree else transform(tree).asInstanceOf[ValDef]
- def transformValDefs(trees: List[ValDef]): List[ValDef] =
- trees mapConserve (transformValDef(_))
- def transformValDefss(treess: List[List[ValDef]]): List[List[ValDef]] =
- treess mapConserve (transformValDefs(_))
- def transformCaseDefs(trees: List[CaseDef]): List[CaseDef] =
- trees mapConserve (tree => transform(tree).asInstanceOf[CaseDef])
- def transformIdents(trees: List[Ident]): List[Ident] =
- trees mapConserve (tree => transform(tree).asInstanceOf[Ident])
- def transformStats(stats: List[Tree], exprOwner: Symbol): List[Tree] =
- stats mapConserve (stat =>
- if (exprOwner != currentOwner && stat.isTerm) atOwner(exprOwner)(transform(stat))
- else transform(stat)) filter (EmptyTree !=)
- def transformModifiers(mods: Modifiers): Modifiers =
- Modifiers(mods.flags, mods.privateWithin, transformTrees(mods.annotations), mods.positions)
-
- def atOwner[A](owner: Symbol)(trans: => A): A = {
- val prevOwner = currentOwner
- currentOwner = owner
- val result = trans
- currentOwner = prevOwner
- result
+ class ForeachPartialTreeTraverser(pf: PartialFunction[Tree, Tree]) extends Traverser {
+ override def traverse(tree: Tree) {
+ val t = if (pf isDefinedAt tree) pf(tree) else tree
+ super.traverse(t)
}
}
- private[scala] def duplicateTree(tree: Tree): Tree = duplicator transform tree
-
- private lazy val duplicator = new Transformer {
- override val treeCopy = new StrictTreeCopier
- override def transform(t: Tree) = {
- val t1 = super.transform(t)
- if ((t1 ne t) && isRangePos(t1.pos)) t1 setPos focusPos(t.pos)
- t1
+ class ChangeOwnerTraverser(val oldowner: Symbol, val newowner: Symbol) extends Traverser {
+ def changeOwner(tree: Tree) = {
+ if ((tree.isDef || tree.isInstanceOf[Function]) &&
+ tree.symbol != NoSymbol && tree.symbol.owner == oldowner)
+ tree.symbol.owner = newowner
+ }
+ override def traverse(tree: Tree) {
+ changeOwner(tree)
+ super.traverse(tree)
}
}
private class ShallowDuplicator(orig: Tree) extends Transformer {
- override val treeCopy = new StrictTreeCopier
+ override val treeCopy = newStrictTreeCopier
override def transform(tree: Tree) =
if (tree eq orig) super.transform(tree)
else tree
@@ -1591,239 +369,5 @@ trait Trees /*extends reflect.generic.Trees*/ { self: SymbolTable =>
def apply[T <: Tree](tree: T): T = transform(tree).asInstanceOf[T]
override def toString() = "TreeSymSubstituter/" + substituterString("Symbol", "Symbol", from, to)
}
-
- class ChangeOwnerTraverser(val oldowner: Symbol, val newowner: Symbol) extends Traverser {
- def changeOwner(tree: Tree) = {
- if ((tree.isDef || tree.isInstanceOf[Function]) &&
- tree.symbol != NoSymbol && tree.symbol.owner == oldowner)
- tree.symbol.owner = newowner
- }
- override def traverse(tree: Tree) {
- changeOwner(tree)
- super.traverse(tree)
- }
- }
-
- object posAssigner extends Traverser {
- var pos: Position = _
- override def traverse(t: Tree) {
- if (t != EmptyTree && t.pos == NoPosition) {
- t.setPos(pos)
- super.traverse(t)
- }
- }
- }
-
- def atPos[T <: Tree](pos: Position)(tree: T): T = {
- posAssigner.pos = pos
- posAssigner.traverse(tree)
- tree
- }
-
- class ForeachPartialTreeTraverser(pf: PartialFunction[Tree, Tree]) extends Traverser {
- override def traverse(tree: Tree) {
- val t = if (pf isDefinedAt tree) pf(tree) else tree
- super.traverse(t)
- }
- }
-
- class ForeachTreeTraverser(f: Tree => Unit) extends Traverser {
- override def traverse(t: Tree) {
- f(t)
- super.traverse(t)
- }
- }
-
- class FilterTreeTraverser(p: Tree => Boolean) extends Traverser {
- val hits = new ListBuffer[Tree]
- override def traverse(t: Tree) {
- if (p(t)) hits += t
- super.traverse(t)
- }
- }
-
- class FindTreeTraverser(p: Tree => Boolean) extends Traverser {
- var result: Option[Tree] = None
- override def traverse(t: Tree) {
- if (result.isEmpty) {
- if (p(t)) result = Some(t)
- super.traverse(t)
- }
- }
- }
-
- object resetPos extends Traverser {
- override def traverse(t: Tree) {
- if (t != EmptyTree) t.setPos(NoPosition)
- super.traverse(t)
- }
- }
-
-
- /** resets symbol and tpe fields in a tree, @see ResetAttrsTraverse
- */
- def resetAllAttrs[A<:Tree](x:A): A = { new ResetAttrsTraverser().traverse(x); x }
- def resetLocalAttrs[A<:Tree](x:A): A = { new ResetLocalAttrsTraverser().traverse(x); x }
-
- /** A traverser which resets symbol and tpe fields of all nodes in a given tree
- * except for (1) TypeTree nodes, whose <code>.tpe</code> field is kept, and
- * (2) This(pkg) nodes, where pkg refers to a package symbol -- their attributes are kept, and
- * (3) if a <code>.symbol</code> field refers to a symbol which is defined
- * outside the tree, it is also kept.
- *
- * (2) is necessary because some This(pkg) are generated where pkg is not
- * an enclosing package.n In that case, resetting the symbol would cause the
- * next type checking run to fail. See #3152.
- *
- * (bq:) This traverser has mutable state and should be discarded after use
- */
- private class ResetAttrsTraverser extends Traverser {
- protected def isLocal(sym: Symbol): Boolean = true
- protected def resetDef(tree: Tree) {
- tree.symbol = NoSymbol
- }
- override def traverse(tree: Tree): Unit = {
- tree match {
- case _: DefTree | Function(_, _) | Template(_, _, _) =>
- resetDef(tree)
- tree.tpe = null
- case tpt: TypeTree =>
- if (tpt.wasEmpty) tree.tpe = null
- case This(_) if tree.symbol != null && tree.symbol.isPackageClass =>
- ;
- case EmptyTree =>
- ;
- case _ =>
- if (tree.hasSymbol && isLocal(tree.symbol)) tree.symbol = NoSymbol
- tree.tpe = null
- }
- super.traverse(tree)
- }
- }
-
- private class ResetLocalAttrsTraverser extends ResetAttrsTraverser {
- private val erasedSyms = HashSet[Symbol](8)
- override protected def isLocal(sym: Symbol) = erasedSyms(sym)
- override protected def resetDef(tree: Tree) {
- erasedSyms addEntry tree.symbol
- super.resetDef(tree)
- }
- override def traverse(tree: Tree): Unit = tree match {
- case Template(parents, self, body) =>
- for (stat <- body)
- if (stat.isDef) erasedSyms.addEntry(stat.symbol)
- super.traverse(tree)
- case _ =>
- super.traverse(tree)
- }
- }
-
- /* A standard pattern match
- case EmptyTree =>
- case PackageDef(pid, stats) =>
- // package pid { stats }
- case ClassDef(mods, name, tparams, impl) =>
- // mods class name [tparams] impl where impl = extends parents { defs }
- case ModuleDef(mods, name, impl) => (eliminated by refcheck)
- // mods object name impl where impl = extends parents { defs }
- case ValDef(mods, name, tpt, rhs) =>
- // mods val name: tpt = rhs
- // note missing type information is expressed by tpt = TypeTree()
- case DefDef(mods, name, tparams, vparamss, tpt, rhs) =>
- // mods def name[tparams](vparams_1)...(vparams_n): tpt = rhs
- // note missing type information is expressed by tpt = TypeTree()
- case TypeDef(mods, name, tparams, rhs) => (eliminated by erasure)
- // mods type name[tparams] = rhs
- // mods type name[tparams] >: lo <: hi, where lo, hi are in a TypeBoundsTree,
- and DEFERRED is set in mods
- case LabelDef(name, params, rhs) =>
- // used for tailcalls and like
- // while/do are desugared to label defs as follows:
- // while (cond) body ==> LabelDef($L, List(), if (cond) { body; L$() } else ())
- // do body while (cond) ==> LabelDef($L, List(), body; if (cond) L$() else ())
- case Import(expr, selectors) => (eliminated by typecheck)
- // import expr.{selectors}
- // Selectors are a list of pairs of names (from, to).
- // The last (and maybe only name) may be a nme.WILDCARD
- // for instance
- // import qual.{x, y => z, _} would be represented as
- // Import(qual, List(("x", "x"), ("y", "z"), (WILDCARD, null)))
- case Template(parents, self, body) =>
- // extends parents { self => body }
- // if self is missing it is represented as emptyValDef
- case Block(stats, expr) =>
- // { stats; expr }
- case CaseDef(pat, guard, body) => (eliminated by transmatch/explicitouter)
- // case pat if guard => body
- case Alternative(trees) => (eliminated by transmatch/explicitouter)
- // pat1 | ... | patn
- case Star(elem) => (eliminated by transmatch/explicitouter)
- // pat*
- case Bind(name, body) => (eliminated by transmatch/explicitouter)
- // name @ pat
- case UnApply(fun: Tree, args) (introduced by typer, eliminated by transmatch/explicitouter)
- // used for unapply's
- case ArrayValue(elemtpt, trees) => (introduced by uncurry)
- // used to pass arguments to vararg arguments
- // for instance, printf("%s%d", foo, 42) is translated to after uncurry to:
- // Apply(
- // Ident("printf"),
- // Literal("%s%d"),
- // ArrayValue(<Any>, List(Ident("foo"), Literal(42))))
- case Function(vparams, body) => (eliminated by lambdaLift)
- // vparams => body where vparams:List[ValDef]
- case Assign(lhs, rhs) =>
- // lhs = rhs
- case If(cond, thenp, elsep) =>
- // if (cond) thenp else elsep
- case Match(selector, cases) =>
- // selector match { cases }
- case Return(expr) =>
- // return expr
- case Try(block, catches, finalizer) =>
- // try block catch { catches } finally finalizer where catches: List[CaseDef]
- case Throw(expr) =>
- // throw expr
- case New(tpt) =>
- // new tpt always in the context: (new tpt).<init>[targs](args)
- case Typed(expr, tpt) => (eliminated by erasure)
- // expr: tpt
- case TypeApply(fun, args) =>
- // fun[args]
- case Apply(fun, args) =>
- // fun(args)
- // for instance fun[targs](args) is expressed as Apply(TypeApply(fun, targs), args)
- case ApplyDynamic(qual, args) (introduced by erasure, eliminated by cleanup)
- // fun(args)
- case Super(qual, mix) =>
- // qual.super[mix] if qual and/or mix is empty, ther are tpnme.EMPTY
- case This(qual) =>
- // qual.this
- case Select(qualifier, selector) =>
- // qualifier.selector
- case Ident(name) =>
- // name
- // note: type checker converts idents that refer to enclosing fields or methods
- // to selects; name ==> this.name
- case Literal(value) =>
- // value
- case TypeTree() => (introduced by refcheck)
- // a type that's not written out, but given in the tpe attribute
- case Annotated(annot, arg) => (eliminated by typer)
- // arg @annot for types, arg: @annot for exprs
- case SingletonTypeTree(ref) => (eliminated by uncurry)
- // ref.type
- case SelectFromTypeTree(qualifier, selector) => (eliminated by uncurry)
- // qualifier # selector, a path-dependent type p.T is expressed as p.type # T
- case CompoundTypeTree(templ: Template) => (eliminated by uncurry)
- // parent1 with ... with parentN { refinement }
- case AppliedTypeTree(tpt, args) => (eliminated by uncurry)
- // tpt[args]
- case TypeBoundsTree(lo, hi) => (eliminated by uncurry)
- // >: lo <: hi
- case ExistentialTypeTree(tpt, whereClauses) => (eliminated by uncurry)
- // tpt forSome { whereClauses }
- case SelectFromArray(_, _, _) => (created and eliminated by erasure)
-*/
}
diff --git a/src/compiler/scala/reflect/internal/Types.scala b/src/compiler/scala/reflect/internal/Types.scala
index 840d66c558..f17c766001 100644
--- a/src/compiler/scala/reflect/internal/Types.scala
+++ b/src/compiler/scala/reflect/internal/Types.scala
@@ -70,7 +70,7 @@ import util.Statistics._
// Not presently used, it seems.
*/
-trait Types /*extends reflect.generic.Types*/ { self: SymbolTable =>
+trait Types extends api.Types { self: SymbolTable =>
import definitions._
//statistics
@@ -235,7 +235,7 @@ trait Types /*extends reflect.generic.Types*/ { self: SymbolTable =>
}
/** The base class for all types */
- abstract class Type {
+ abstract class Type extends AbsType {
/** Types for which asSeenFrom always is the identity, no matter what
* prefix or owner.
@@ -1166,7 +1166,8 @@ trait Types /*extends reflect.generic.Types*/ { self: SymbolTable =>
}
final class UniqueThisType(sym: Symbol) extends ThisType(sym) with UniqueType { }
- object ThisType {
+
+ object ThisType extends ThisTypeExtractor {
def apply(sym: Symbol): Type = {
if (!phase.erasedTypes) unique(new UniqueThisType(sym))
else if (sym.isImplClass) sym.typeOfThis
@@ -1223,7 +1224,8 @@ trait Types /*extends reflect.generic.Types*/ { self: SymbolTable =>
}
final class UniqueSingleType(pre: Type, sym: Symbol) extends SingleType(pre, sym) with UniqueType { }
- object SingleType {
+
+ object SingleType extends SingleTypeExtractor {
def apply(pre: Type, sym: Symbol): Type = {
unique(new UniqueSingleType(pre, sym))
}
@@ -1241,7 +1243,8 @@ trait Types /*extends reflect.generic.Types*/ { self: SymbolTable =>
}
final class UniqueSuperType(thistp: Type, supertp: Type) extends SuperType(thistp, supertp) with UniqueType { }
- object SuperType {
+
+ object SuperType extends SuperTypeExtractor {
def apply(thistp: Type, supertp: Type): Type = {
if (phase.erasedTypes) supertp
else unique(new UniqueSuperType(thistp, supertp))
@@ -1264,7 +1267,8 @@ trait Types /*extends reflect.generic.Types*/ { self: SymbolTable =>
}
final class UniqueTypeBounds(lo: Type, hi: Type) extends TypeBounds(lo, hi) with UniqueType { }
- object TypeBounds {
+
+ object TypeBounds extends TypeBoundsExtractor {
def empty: TypeBounds = apply(NothingClass.tpe, AnyClass.tpe)
def upper(hi: Type): TypeBounds = apply(NothingClass.tpe, hi)
def lower(lo: Type): TypeBounds = apply(lo, AnyClass.tpe)
@@ -1497,7 +1501,8 @@ trait Types /*extends reflect.generic.Types*/ { self: SymbolTable =>
final class RefinedType0(parents: List[Type], decls: Scope, clazz: Symbol) extends RefinedType(parents, decls) {
override def typeSymbol = clazz
}
- object RefinedType {
+
+ object RefinedType extends RefinedTypeExtractor {
def apply(parents: List[Type], decls: Scope, clazz: Symbol): RefinedType =
new RefinedType0(parents, decls, clazz)
}
@@ -1642,6 +1647,8 @@ trait Types /*extends reflect.generic.Types*/ { self: SymbolTable =>
override def kind = "ClassInfoType"
}
+ object ClassInfoType extends ClassInfoTypeExtractor
+
class PackageClassInfoType(decls: Scope, clazz: Symbol)
extends ClassInfoType(List(), decls, clazz)
@@ -1668,7 +1675,8 @@ trait Types /*extends reflect.generic.Types*/ { self: SymbolTable =>
private lazy val _tpe: Type = value.tpe
override def underlying: Type = _tpe
}
- object ConstantType {
+
+ object ConstantType extends ConstantTypeExtractor {
def apply(value: Constant): ConstantType = {
unique(new UniqueConstantType(value)).asInstanceOf[ConstantType]
}
@@ -2043,7 +2051,8 @@ A type's typeSymbol should never be inspected directly.
}
final class UniqueTypeRef(pre: Type, sym: Symbol, args: List[Type]) extends TypeRef(pre, sym, args) with UniqueType { }
- object TypeRef {
+
+ object TypeRef extends TypeRefExtractor {
def apply(pre: Type, sym: Symbol, args: List[Type]): Type = {
unique(new UniqueTypeRef(pre, sym, args))
}
@@ -2120,6 +2129,8 @@ A type's typeSymbol should never be inspected directly.
override def kind = "MethodType"
}
+ object MethodType extends MethodTypeExtractor
+
class JavaMethodType(ps: List[Symbol], rt: Type) extends MethodType(ps, rt) {
override def isJava = true
}
@@ -2147,6 +2158,8 @@ A type's typeSymbol should never be inspected directly.
override def kind = "NullaryMethodType"
}
+ object NullaryMethodType extends NullaryMethodTypeExtractor
+
/** A type function or the type of a polymorphic value (and thus of kind *).
*
* Before the introduction of NullaryMethodType, a polymorphic nullary method (e.g, def isInstanceOf[T]: Boolean)
@@ -2208,6 +2221,8 @@ A type's typeSymbol should never be inspected directly.
override def kind = "PolyType"
}
+ object PolyType extends PolyTypeExtractor
+
case class ExistentialType(quantified: List[Symbol],
override val underlying: Type) extends RewrappingTypeProxy
{
@@ -2305,6 +2320,8 @@ A type's typeSymbol should never be inspected directly.
}
}
+ object ExistentialType extends ExistentialTypeExtractor
+
/** A class containing the alternatives and type prefix of an overloaded symbol.
* Not used after phase `typer`.
*/
@@ -2652,6 +2669,8 @@ A type's typeSymbol should never be inspected directly.
override def kind = "AnnotatedType"
}
+ object AnnotatedType extends AnnotatedTypeExtractor
+
/** A class representing types with a name. When an application uses
* named arguments, the named argument types for calling isApplicable
* are represented as NamedType.
@@ -3638,7 +3657,6 @@ A type's typeSymbol should never be inspected directly.
}
}
-
override def mapOver(tree: Tree, giveup: ()=>Nothing): Tree = {
object trans extends TypeMapTransformer {
diff --git a/src/compiler/scala/reflect/internal/pickling/UnPickler.scala b/src/compiler/scala/reflect/internal/pickling/UnPickler.scala
index 0082f97835..1f54edbdc5 100644
--- a/src/compiler/scala/reflect/internal/pickling/UnPickler.scala
+++ b/src/compiler/scala/reflect/internal/pickling/UnPickler.scala
@@ -192,7 +192,7 @@ abstract class UnPickler /*extends reflect.generic.UnPickler*/ {
val name = readNameRef()
val owner = if (atEnd) definitions.RootClass else readSymbolRef()
- def fromName(name: Name) = mkTermName(name) match {
+ def fromName(name: Name) = name.toTermName match {
case nme.ROOT => definitions.RootClass
case nme.ROOTPKG => definitions.RootPackage
case _ =>
@@ -276,14 +276,14 @@ abstract class UnPickler /*extends reflect.generic.UnPickler*/ {
}
finishSym(tag match {
- case TYPEsym => owner.newAbstractType(mkTypeName(name))
- case ALIASsym => owner.newAliasType(mkTypeName(name))
+ case TYPEsym => owner.newAbstractType(name.toTypeName)
+ case ALIASsym => owner.newAliasType(name.toTypeName)
case CLASSsym =>
val sym = (isClassRoot, isModuleFlag) match {
case (true, true) => moduleRoot.moduleClass
case (true, false) => classRoot
- case (false, true) => owner.newModuleClass(mkTypeName(name))
- case (false, false) => owner.newClass(mkTypeName(name))
+ case (false, true) => owner.newModuleClass(name.toTypeName)
+ case (false, false) => owner.newClass(name.toTypeName)
}
if (!atEnd)
sym.typeOfThis = newLazyTypeRef(readNat())
@@ -542,7 +542,7 @@ abstract class UnPickler /*extends reflect.generic.UnPickler*/ {
setSymModsName()
val impl = readTemplateRef()
val tparams = until(end, readTypeDefRef)
- ClassDef(mods, mkTypeName(name), tparams, impl)
+ ClassDef(mods, name.toTypeName, tparams, impl)
case MODULEtree =>
setSymModsName()
@@ -566,7 +566,7 @@ abstract class UnPickler /*extends reflect.generic.UnPickler*/ {
setSymModsName()
val rhs = readTreeRef()
val tparams = until(end, readTypeDefRef)
- TypeDef(mods, mkTypeName(name), tparams, rhs)
+ TypeDef(mods, name.toTypeName, tparams, rhs)
case LABELtree =>
setSymName()
@@ -777,8 +777,8 @@ abstract class UnPickler /*extends reflect.generic.UnPickler*/ {
protected def readModifiersRef(): Modifiers = at(readNat(), readModifiers)
protected def readTreeRef(): Tree = at(readNat(), readTree)
- protected def readTypeNameRef(): TypeName = mkTypeName(readNameRef())
- protected def readTermNameRef(): TermName = mkTermName(readNameRef())
+ protected def readTypeNameRef(): TypeName = readNameRef().toTypeName
+ protected def readTermNameRef(): TermName = readNameRef().toTermName
protected def readTemplateRef(): Template =
readTreeRef() match {
diff --git a/src/compiler/scala/reflect/runtime/AbstractFile.scala b/src/compiler/scala/reflect/runtime/AbstractFile.scala
new file mode 100644
index 0000000000..04f18bcd3b
--- /dev/null
+++ b/src/compiler/scala/reflect/runtime/AbstractFile.scala
@@ -0,0 +1,5 @@
+package scala.reflect.runtime
+
+class AbstractFile(val jfile: java.io.File) {
+ def path: String = jfile.getPath()
+} \ No newline at end of file
diff --git a/src/compiler/scala/reflect/runtime/Universe.scala b/src/compiler/scala/reflect/runtime/Universe.scala
new file mode 100644
index 0000000000..c570e75eb7
--- /dev/null
+++ b/src/compiler/scala/reflect/runtime/Universe.scala
@@ -0,0 +1,37 @@
+package scala.reflect
+package runtime
+
+class Universe extends internal.SymbolTable {
+
+ type AbstractFileType = AbstractFile
+
+ def picklerPhase = internal.NoPhase
+
+ //val treePrinter = null
+
+ val gen = new internal.TreeGen { val global: Universe.this.type = Universe.this }
+
+ def settings = null
+ def forInteractive = false
+ def forScaladoc = false
+
+ val phaseWithId: Array[internal.Phase] = Array()
+ val currentRunId = 0
+ def log(msg: => AnyRef): Unit = println(" [] "+msg)
+ def rootLoader = null // not needed because RootClass will get a PackageType in Definitions anyway.
+
+ private def packageType(clazz: Symbol) = new ClassInfoType(List(), newScope, clazz)
+
+ definitions.RootClass.setInfo(packageType(definitions.RootClass))
+
+ type TreeCopier = TreeCopierOps
+ def newStrictTreeCopier: TreeCopier = new StrictTreeCopier
+ def newLazyTreeCopier: TreeCopier = new LazyTreeCopier
+
+ def focusPos(pos: Position) = pos
+ def isRangePos(pos: Position) = false
+ def showPos(pos: Position) = "<unknown position>"
+
+ type Position = String // source file?
+ val NoPosition = ""
+}
diff --git a/src/compiler/scala/tools/nsc/ast/TreeInfo.scala b/src/compiler/scala/tools/nsc/ast/TreeInfo.scala
new file mode 100644
index 0000000000..bc8ec07ebc
--- /dev/null
+++ b/src/compiler/scala/tools/nsc/ast/TreeInfo.scala
@@ -0,0 +1,45 @@
+/* NSC -- new Scala compiler
+ * Copyright 2005-2011 LAMP/EPFL
+ * @author Martin Odersky
+ */
+
+package scala.tools.nsc
+package ast
+
+import reflect.internal.Flags._
+import symtab._
+import util.HashSet
+
+/** This class ...
+ *
+ * @author Martin Odersky
+ * @version 1.0
+ */
+abstract class TreeInfo extends reflect.internal.TreeInfo {
+ val global: Global
+ import global._
+
+ import definitions.ThrowableClass
+
+ /** Is tree legal as a member definition of an interface?
+ */
+ override def isInterfaceMember(tree: Tree): Boolean = tree match {
+ case DocDef(_, definition) => isInterfaceMember(definition)
+ case _ => super.isInterfaceMember(tree)
+ }
+
+ /** Is tree a pure (i.e. non-side-effecting) definition?
+ */
+ override def isPureDef(tree: Tree): Boolean = tree match {
+ case DocDef(_, definition) => isPureDef(definition)
+ case _ => super.isPureDef(tree)
+ }
+
+ /** Does list of trees start with a definition of
+ * a class of module with given name (ignoring imports)
+ */
+ override def firstDefinesClassOrObject(trees: List[Tree], name: Name): Boolean = trees match {
+ case ClassDef(_, `name`, _, _) :: Nil => true
+ case _ => super.firstDefinesClassOrObject(trees, name)
+ }
+}
diff --git a/src/compiler/scala/tools/nsc/ast/TreePrinters.scala b/src/compiler/scala/tools/nsc/ast/TreePrinters.scala
index 1a0ddd4e1e..34f8cdc626 100644
--- a/src/compiler/scala/tools/nsc/ast/TreePrinters.scala
+++ b/src/compiler/scala/tools/nsc/ast/TreePrinters.scala
@@ -44,6 +44,30 @@ trait TreePrinters extends reflect.internal.TreePrinters { this: Global =>
}
}
+ // overflow cases missing from TreePrinter in reflect.api
+ override def xprintRaw(treePrinter: super.TreePrinter, tree: Tree) = tree match {
+ case DocDef(comment, definition) =>
+ treePrinter.print(comment.raw)
+ treePrinter.println()
+ treePrinter.print(definition)
+
+ case AssignOrNamedArg(lhs, rhs) =>
+ treePrinter.print(lhs)
+ treePrinter.print(" = ")
+ treePrinter.print(rhs)
+
+ case TypeTreeWithDeferredRefCheck() =>
+ treePrinter.print("<tree with deferred refcheck>")
+
+ case SelectFromArray(qualifier, name, _) =>
+ treePrinter.print(qualifier)
+ treePrinter.print(".<arr>")
+ treePrinter.print(treePrinter.symName(tree, name))
+
+ case _ =>
+ super.xprintRaw(treePrinter, tree)
+ }
+
/** A tree printer which is stingier about vertical whitespace and unnecessary
* punctuation than the standard one.
*/
diff --git a/src/compiler/scala/tools/nsc/ast/Trees.scala b/src/compiler/scala/tools/nsc/ast/Trees.scala
index 008eb8372a..42a4698793 100644
--- a/src/compiler/scala/tools/nsc/ast/Trees.scala
+++ b/src/compiler/scala/tools/nsc/ast/Trees.scala
@@ -6,11 +6,291 @@
package scala.tools.nsc
package ast
+import scala.reflect.internal.Flags.BYNAMEPARAM
+import scala.reflect.internal.Flags.DEFAULTPARAM
+import scala.reflect.internal.Flags.IMPLICIT
+import scala.reflect.internal.Flags.PARAM
+import scala.reflect.internal.Flags.PARAMACCESSOR
+import scala.reflect.internal.Flags.PRESUPER
+import scala.reflect.internal.Flags.TRAIT
+
+import util.HashSet
+
trait Trees extends reflect.internal.Trees { self: Global =>
+ // --- additional cases --------------------------------------------------------
+
+ /** Only used during parsing */
+ case class Parens(args: List[Tree]) extends Tree
+
+ /** Documented definition, eliminated by analyzer */
+ case class DocDef(comment: DocComment, definition: Tree)
+ extends Tree {
+ override def symbol: Symbol = definition.symbol
+ override def symbol_=(sym: Symbol) { definition.symbol = sym }
+ override def isDef = definition.isDef
+ override def isTerm = definition.isTerm
+ override def isType = definition.isType
+ }
+
+
+ /** Either an assignment or a named argument. Only appears in argument lists,
+ * eliminated by typecheck (doTypedApply)
+ */
+ case class AssignOrNamedArg(lhs: Tree, rhs: Tree)
+ extends TermTree
+
+ /** Array selection <qualifier> . <name> only used during erasure */
+ case class SelectFromArray(qualifier: Tree, name: Name, erasure: Type)
+ extends TermTree with RefTree { }
+
+ /** emitted by typer, eliminated by refchecks */
+ case class TypeTreeWithDeferredRefCheck()(val check: () => TypeTree) extends TypTree
+
+ // --- factory methods ----------------------------------------------------------
+
+ /** Generates a template with constructor corresponding to
+ *
+ * constrmods (vparams1_) ... (vparams_n) preSuper { presupers }
+ * extends superclass(args_1) ... (args_n) with mixins { self => body }
+ *
+ * This gets translated to
+ *
+ * extends superclass with mixins { self =>
+ * presupers' // presupers without rhs
+ * vparamss // abstract fields corresponding to value parameters
+ * def <init>(vparamss) {
+ * presupers
+ * super.<init>(args)
+ * }
+ * body
+ * }
+ */
+ def Template(parents: List[Tree], self: ValDef, constrMods: Modifiers, vparamss: List[List[ValDef]], argss: List[List[Tree]], body: List[Tree], superPos: Position): Template = {
+ /* Add constructor to template */
+
+ // create parameters for <init> as synthetic trees.
+ var vparamss1 =
+ vparamss map (vps => vps.map { vd =>
+ atPos(focusPos(vd.pos)) {
+ ValDef(
+ Modifiers(vd.mods.flags & (IMPLICIT | DEFAULTPARAM | BYNAMEPARAM) | PARAM | PARAMACCESSOR) withAnnotations vd.mods.annotations,
+ vd.name, vd.tpt.duplicate, vd.rhs.duplicate)
+ }})
+ val (edefs, rest) = body span treeInfo.isEarlyDef
+ val (evdefs, etdefs) = edefs partition treeInfo.isEarlyValDef
+ val (lvdefs, gvdefs) = evdefs map {
+ case vdef @ ValDef(mods, name, tpt, rhs) =>
+ val fld = treeCopy.ValDef(
+ vdef.duplicate, mods, name,
+ atPos(focusPos(vdef.pos)) { TypeTree() setOriginal tpt setPos focusPos(tpt.pos) }, // atPos in case
+ EmptyTree)
+ val local = treeCopy.ValDef(vdef, Modifiers(PRESUPER), name, tpt, rhs)
+ (local, fld)
+ } unzip
+
+ val constrs = {
+ if (constrMods hasFlag TRAIT) {
+ if (body forall treeInfo.isInterfaceMember) List()
+ else List(
+ atPos(wrappingPos(superPos, lvdefs)) (
+ DefDef(NoMods, nme.MIXIN_CONSTRUCTOR, List(), List(List()), TypeTree(), Block(lvdefs, Literal(())))))
+ } else {
+ // convert (implicit ... ) to ()(implicit ... ) if its the only parameter section
+ if (vparamss1.isEmpty || !vparamss1.head.isEmpty && vparamss1.head.head.mods.isImplicit)
+ vparamss1 = List() :: vparamss1;
+ val superRef: Tree = atPos(superPos) {
+ Select(Super(This(tpnme.EMPTY), tpnme.EMPTY), nme.CONSTRUCTOR)
+ }
+ val superCall = (superRef /: argss) (Apply)
+ List(
+ atPos(wrappingPos(superPos, lvdefs ::: argss.flatten)) (
+ DefDef(constrMods, nme.CONSTRUCTOR, List(), vparamss1, TypeTree(), Block(lvdefs ::: List(superCall), Literal(())))))
+ }
+ }
+ // println("typed template, gvdefs = "+gvdefs+", parents = "+parents+", constrs = "+constrs)
+ constrs foreach (ensureNonOverlapping(_, parents ::: gvdefs))
+ // vparamss2 are used as field definitions for the class. remove defaults
+ val vparamss2 = vparamss map (vps => vps map { vd =>
+ treeCopy.ValDef(vd, vd.mods &~ DEFAULTPARAM, vd.name, vd.tpt, EmptyTree)
+ })
+ Template(parents, self, gvdefs ::: vparamss2.flatten ::: constrs ::: etdefs ::: rest)
+ }
+
+ /** Construct class definition with given class symbol, value parameters,
+ * supercall arguments and template body.
+ *
+ * @param sym the class symbol
+ * @param constrMods the modifiers for the class constructor, i.e. as in `class C private (...)`
+ * @param vparamss the value parameters -- if they have symbols they
+ * should be owned by `sym`
+ * @param argss the supercall arguments
+ * @param body the template statements without primary constructor
+ * and value parameter fields.
+ */
+ def ClassDef(sym: Symbol, constrMods: Modifiers, vparamss: List[List[ValDef]], argss: List[List[Tree]], body: List[Tree], superPos: Position): ClassDef =
+ ClassDef(sym,
+ Template(sym.info.parents map TypeTree,
+ if (sym.thisSym == sym || phase.erasedTypes) emptyValDef else ValDef(sym.thisSym),
+ constrMods, vparamss, argss, body, superPos))
+
+ // --- subcomponents --------------------------------------------------
+
+ object treeInfo extends {
+ val global: Trees.this.type = self
+ } with TreeInfo
+
lazy val treePrinter = newTreePrinter()
+ // --- additional cases in operations ----------------------------------
+
+ override protected def xtraverse(traverser: Traverser, tree: Tree): Unit = tree match {
+ case Parens(ts) =>
+ traverser.traverseTrees(ts)
+ case DocDef(comment, definition) =>
+ traverser.traverse(definition)
+ case AssignOrNamedArg(lhs, rhs) =>
+ traverser.traverse(lhs); traverser.traverse(rhs)
+ case SelectFromArray(qualifier, selector, erasure) =>
+ traverser.traverse(qualifier)
+ 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)
+ }
+
+ trait TreeCopier extends super.TreeCopierOps {
+ 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 TypeTreeWithDeferredRefCheck(tree: Tree): TypeTreeWithDeferredRefCheck
+ }
+
+ def newStrictTreeCopier: TreeCopier = new StrictTreeCopier
+ def newLazyTreeCopier: TreeCopier = new LazyTreeCopier
+
+ class StrictTreeCopier extends super.StrictTreeCopier with TreeCopier {
+ def DocDef(tree: Tree, comment: DocComment, definition: Tree) =
+ new DocDef(comment, definition).copyAttrs(tree)
+ def AssignOrNamedArg(tree: Tree, lhs: Tree, rhs: Tree) =
+ new AssignOrNamedArg(lhs, rhs).copyAttrs(tree)
+ def SelectFromArray(tree: Tree, qualifier: Tree, selector: Name, erasure: Type) =
+ new SelectFromArray(qualifier, selector, erasure).copyAttrs(tree)
+ def TypeTreeWithDeferredRefCheck(tree: Tree) = tree match {
+ case dc@TypeTreeWithDeferredRefCheck() => new TypeTreeWithDeferredRefCheck()(dc.check).copyAttrs(tree)
+ }
+ }
+
+ class LazyTreeCopier extends super.LazyTreeCopier with TreeCopier {
+ def DocDef(tree: Tree, comment: DocComment, definition: Tree) = tree match {
+ case t @ DocDef(comment0, definition0)
+ if (comment0 == comment) && (definition0 == definition) => t
+ case _ => this.treeCopy.DocDef(tree, comment, definition)
+ }
+ def AssignOrNamedArg(tree: Tree, lhs: Tree, rhs: Tree) = tree match {
+ case t @ AssignOrNamedArg(lhs0, rhs0)
+ if (lhs0 == lhs) && (rhs0 == rhs) => t
+ case _ => this.treeCopy.AssignOrNamedArg(tree, lhs, rhs)
+ }
+ def SelectFromArray(tree: Tree, qualifier: Tree, selector: Name, erasure: Type) = tree match {
+ case t @ SelectFromArray(qualifier0, selector0, _)
+ if (qualifier0 == qualifier) && (selector0 == selector) => t
+ case _ => this.treeCopy.SelectFromArray(tree, qualifier, selector, erasure)
+ }
+ def TypeTreeWithDeferredRefCheck(tree: Tree) = tree match {
+ case t @ TypeTreeWithDeferredRefCheck() => t
+ case _ => this.treeCopy.TypeTreeWithDeferredRefCheck(tree)
+ }
+ }
+
class Transformer extends super.Transformer {
def transformUnit(unit: CompilationUnit) { unit.body = transform(unit.body) }
}
-} \ No newline at end of file
+
+ override protected def xtransform(transformer: super.Transformer, tree: Tree): Tree = tree match {
+ case DocDef(comment, definition) =>
+ transformer.treeCopy.DocDef(tree, comment, transformer.transform(definition))
+ case AssignOrNamedArg(lhs, rhs) =>
+ transformer.treeCopy.AssignOrNamedArg(tree, transformer.transform(lhs), transformer.transform(rhs))
+ case SelectFromArray(qualifier, selector, erasure) =>
+ transformer.treeCopy.SelectFromArray(
+ tree, transformer.transform(qualifier), selector, erasure)
+ case TypeTreeWithDeferredRefCheck() =>
+ transformer.treeCopy.TypeTreeWithDeferredRefCheck(tree)
+ }
+
+ object resetPos extends Traverser {
+ override def traverse(t: Tree) {
+ if (t != EmptyTree) t.setPos(NoPosition)
+ super.traverse(t)
+ }
+ }
+
+ /** resets symbol and tpe fields in a tree, @see ResetAttrsTraverse
+ */
+ def resetAllAttrs[A<:Tree](x:A): A = { new ResetAttrsTraverser().traverse(x); x }
+ def resetLocalAttrs[A<:Tree](x:A): A = { new ResetLocalAttrsTraverser().traverse(x); x }
+
+ /** A traverser which resets symbol and tpe fields of all nodes in a given tree
+ * except for (1) TypeTree nodes, whose <code>.tpe</code> field is kept, and
+ * (2) This(pkg) nodes, where pkg refers to a package symbol -- their attributes are kept, and
+ * (3) if a <code>.symbol</code> field refers to a symbol which is defined
+ * outside the tree, it is also kept.
+ *
+ * (2) is necessary because some This(pkg) are generated where pkg is not
+ * an enclosing package.n In that case, resetting the symbol would cause the
+ * next type checking run to fail. See #3152.
+ *
+ * (bq:) This traverser has mutable state and should be discarded after use
+ */
+ private class ResetAttrsTraverser extends Traverser {
+ protected def isLocal(sym: Symbol): Boolean = true
+ protected def resetDef(tree: Tree) {
+ tree.symbol = NoSymbol
+ }
+ override def traverse(tree: Tree): Unit = {
+ tree match {
+ case _: DefTree | Function(_, _) | Template(_, _, _) =>
+ resetDef(tree)
+ tree.tpe = null
+ case tpt: TypeTree =>
+ if (tpt.wasEmpty) tree.tpe = null
+ case This(_) if tree.symbol != null && tree.symbol.isPackageClass =>
+ ;
+ case EmptyTree =>
+ ;
+ case _ =>
+ if (tree.hasSymbol && isLocal(tree.symbol)) tree.symbol = NoSymbol
+ tree.tpe = null
+ }
+ super.traverse(tree)
+ }
+ }
+
+ private class ResetLocalAttrsTraverser extends ResetAttrsTraverser {
+ private val erasedSyms = HashSet[Symbol](8)
+ override protected def isLocal(sym: Symbol) = erasedSyms(sym)
+ override protected def resetDef(tree: Tree) {
+ erasedSyms addEntry tree.symbol
+ super.resetDef(tree)
+ }
+ override def traverse(tree: Tree): Unit = tree match {
+ case Template(parents, self, body) =>
+ for (stat <- body)
+ if (stat.isDef) erasedSyms.addEntry(stat.symbol)
+ super.traverse(tree)
+ case _ =>
+ super.traverse(tree)
+ }
+ }
+
+ /* New pattern matching cases:
+
+ case Parens(expr) (only used during parsing)
+ case DocDef(comment, defn) => (eliminated by typer)
+ case AssignOrNamedArg(lhs, rhs) => (eliminated by typer)
+ case TypeTreeWithDeferredRefCheck() => (created and eliminated by typer)
+ case SelectFromArray(_, _, _) => (created and eliminated by erasure)
+
+ */
+
+ } \ No newline at end of file
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index a390d0fc7b..023f170c4b 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -2086,7 +2086,7 @@ trait Typers extends Modes {
tree.pos.isRange && context.unit != null && (tree.pos includes context.unit.targetPos)
val localTarget = stats exists includesTargetPos
def typedStat(stat: Tree): Tree = {
- if (context.owner.isRefinementClass && !treeInfo.isDeclaration(stat))
+ if (context.owner.isRefinementClass && !treeInfo.isDeclarationOrTypeDef(stat))
errorTree(stat, "only declarations allowed here")
else
stat match {
diff --git a/src/continuations/plugin/scala/tools/selectivecps/SelectiveCPSTransform.scala b/src/continuations/plugin/scala/tools/selectivecps/SelectiveCPSTransform.scala
index 167ebe08c6..f0c389bb11 100644
--- a/src/continuations/plugin/scala/tools/selectivecps/SelectiveCPSTransform.scala
+++ b/src/continuations/plugin/scala/tools/selectivecps/SelectiveCPSTransform.scala
@@ -353,7 +353,7 @@ abstract class SelectiveCPSTransform extends PluginComponent with
val argSym = currentOwner.newValue(vd.symbol.name).setInfo(tpe)
val argDef = localTyper.typed(ValDef(argSym, Select(ctxRef, ctxRef.tpe.member("getTrivialValue"))))
val switchExpr = localTyper.typed(atPos(vd.symbol.pos) {
- val body2 = duplicateTree(mkBlock(bodyStms, bodyExpr)) // dup before typing!
+ val body2 = mkBlock(bodyStms, bodyExpr).duplicate // dup before typing!
If(Select(ctxRef, ctxSym.tpe.member("isTrivial")),
applyTrivial(argSym, mkBlock(argDef::bodyStms, bodyExpr)),
applyCombinatorFun(ctxRef, body2))