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 | |
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.
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)) |