diff options
author | Martin Odersky <odersky@gmail.com> | 2011-07-11 09:00:48 +0000 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2011-07-11 09:00:48 +0000 |
commit | 9e1d24d64283a4caf47cb68c00298538ca0b9999 (patch) | |
tree | 368175c8b2adcc68b671b3b9d2acb8821cf04214 /src | |
parent | 7d4cff1dc6040d951b09f8df4af288d16ef53de2 (diff) | |
download | scala-9e1d24d64283a4caf47cb68c00298538ca0b9999.tar.gz scala-9e1d24d64283a4caf47cb68c00298538ca0b9999.tar.bz2 scala-9e1d24d64283a4caf47cb68c00298538ca0b9999.zip |
Refactored reflection into reflect.api and refl...
Refactored reflection into reflect.api and reflect.internal. Severed the
last remaining dependency on reflect.generic. Review by extempore.
Diffstat (limited to 'src')
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)) |