aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2013-02-19 16:24:16 +0100
committerMartin Odersky <odersky@gmail.com>2013-02-19 16:24:16 +0100
commit2c864fae1dd861392368de5be8488ea6842de72e (patch)
treebe6ca9b7d376889ca981c092c924c0459063e8f7
parent5c9433161e116704730693254fdaf161c69cbcb5 (diff)
parent51f7cf3cc33fc357881c0e413eb55b9253e2c22d (diff)
downloaddotty-2c864fae1dd861392368de5be8488ea6842de72e.tar.gz
dotty-2c864fae1dd861392368de5be8488ea6842de72e.tar.bz2
dotty-2c864fae1dd861392368de5be8488ea6842de72e.zip
Merge branch 'simplified-completers'
-rw-r--r--src/dotty/tools/dotc/core/Annotations.scala34
-rw-r--r--src/dotty/tools/dotc/core/PluggableTransformers.scala102
-rw-r--r--src/dotty/tools/dotc/core/SymDenotations.scala67
-rw-r--r--src/dotty/tools/dotc/core/SymbolLoaders.scala2
-rw-r--r--src/dotty/tools/dotc/core/Symbols.scala55
-rw-r--r--src/dotty/tools/dotc/core/Trees.scala405
-rw-r--r--src/dotty/tools/dotc/core/TypedTreeGen.scala236
-rw-r--r--src/dotty/tools/dotc/core/TypedTrees.scala293
-rw-r--r--src/dotty/tools/dotc/core/pickling/ClassfileParser.scala98
-rw-r--r--src/dotty/tools/dotc/core/pickling/UnPickler.scala37
10 files changed, 927 insertions, 402 deletions
diff --git a/src/dotty/tools/dotc/core/Annotations.scala b/src/dotty/tools/dotc/core/Annotations.scala
index 9cbf5c8e4..c91d0c409 100644
--- a/src/dotty/tools/dotc/core/Annotations.scala
+++ b/src/dotty/tools/dotc/core/Annotations.scala
@@ -1,53 +1,53 @@
package dotty.tools.dotc.core
-import Symbols._, Trees._, Types._, Positions._, Contexts._, Constants._, TypedTrees._
+import Symbols._, Types._, Positions._, Contexts._, Constants._, TypedTrees._
object Annotations {
abstract class Annotation {
- def tree: TypedTree
+ def tree: Tree
def symbol(implicit ctx: Context): Symbol = tree.tpe.typeSymbol
def matches(cls: Symbol)(implicit ctx: Context): Boolean = symbol.isNonBottomSubClass(cls)
def appliesToModule: Boolean = ???
}
- case class ConcreteAnnotation(val tree: TypedTree) extends Annotation
+ case class ConcreteAnnotation(val tree: Tree) extends Annotation
object Annotation {
- def apply(tree: TypedTree) = ConcreteAnnotation(tree)
+ def apply(tree: Tree) = ConcreteAnnotation(tree)
- def apply(cls: ClassSymbol, arg: TypedTree)(implicit ctx: Context): Annotation =
+ def apply(cls: ClassSymbol, arg: Tree)(implicit ctx: Context): Annotation =
apply(cls, arg :: Nil)
- def apply(cls: ClassSymbol, arg1: TypedTree, arg2: TypedTree)(implicit ctx: Context): Annotation =
+ def apply(cls: ClassSymbol, arg1: Tree, arg2: Tree)(implicit ctx: Context): Annotation =
apply(cls, arg1 :: arg2 :: Nil)
- def apply(cls: ClassSymbol, args: List[TypedTree])(implicit ctx: Context): Annotation =
+ def apply(cls: ClassSymbol, args: List[Tree])(implicit ctx: Context): Annotation =
apply(cls.typeConstructor, args)
- def apply(atp: Type, arg: TypedTree)(implicit ctx: Context): Annotation =
+ def apply(atp: Type, arg: Tree)(implicit ctx: Context): Annotation =
apply(atp, arg :: Nil)
- def apply(atp: Type, arg1: TypedTree, arg2: TypedTree)(implicit ctx: Context): Annotation =
+ def apply(atp: Type, arg1: Tree, arg2: Tree)(implicit ctx: Context): Annotation =
apply(atp, arg1 :: arg2 :: Nil)
- def apply(atp: Type, args: List[TypedTree])(implicit ctx: Context): Annotation =
- apply(tpd.New(atp, args))
+ def apply(atp: Type, args: List[Tree])(implicit ctx: Context): Annotation =
+ apply(New(atp, args))
def makeAlias(sym: TermSymbol)(implicit ctx: Context) =
- apply(defn.AliasAnnot, List(tpd.Ident(TermRef(sym.owner.thisType, sym.name, sym.signature))))
+ apply(defn.AliasAnnot, List(Ident(TermRef(sym.owner.thisType, sym.name, sym.signature))))
def makeChild(sym: Symbol)(implicit ctx: Context) =
- apply(defn.ChildAnnot, List(tpd.Ident(NamedType(sym.owner.thisType, sym.name))))
+ apply(defn.ChildAnnot, List(Ident(NamedType(sym.owner.thisType, sym.name))))
}
- def makeLiteralAnnotArg(const: Constant): TypedTree = ???
+ def makeLiteralAnnotArg(const: Constant): Tree = ???
- def makeArrayAnnotArg(elems: Array[TypedTree]): TypedTree = ???
+ def makeArrayAnnotArg(elems: Array[Tree]): Tree = ???
- def makeNestedAnnotArg(annot: Annotation): TypedTree = annot.tree
+ def makeNestedAnnotArg(annot: Annotation): Tree = annot.tree
def ThrowsAnnotation(cls: ClassSymbol)(implicit ctx: Context) =
- Annotation(defn.ThrowsAnnot, tpd.Ident(TypeRef(cls.owner.thisType, cls.name)))
+ Annotation(defn.ThrowsAnnot, Ident(TypeRef(cls.owner.thisType, cls.name)))
} \ No newline at end of file
diff --git a/src/dotty/tools/dotc/core/PluggableTransformers.scala b/src/dotty/tools/dotc/core/PluggableTransformers.scala
new file mode 100644
index 000000000..b0b2ca134
--- /dev/null
+++ b/src/dotty/tools/dotc/core/PluggableTransformers.scala
@@ -0,0 +1,102 @@
+package dotty.tools.dotc
+package core
+
+
+object PluggableTransformers {
+
+ import Trees._, Contexts._
+
+ abstract class PluggableTransformer[T] extends TreeTransformer[T, Context] {
+ type PluginOp[-N <: Tree[T]] = N => Tree[T]
+
+ private[this] var _ctx: Context = _
+ private[this] var _oldTree: Tree[T] = _
+
+ protected implicit def ctx: Context = _ctx
+ protected def oldTree: Tree[T] = _oldTree
+ protected def thisTransformer: PluggableTransformer[T] = this
+
+ class PluginOps[-N <: Tree[T]](op: PluginOp[N], val next: Plugins) {
+ def apply(tree: N, old: Tree[T], c: Context): Tree[T] = {
+ val savedCtx = _ctx
+ val savedOld = _oldTree
+ try {
+ op(tree)
+ } finally {
+ _oldTree = savedOld
+ _ctx = savedCtx
+ }
+ }
+ }
+
+ val NoOp: PluginOp[Tree[T]] = identity
+ val NoOps = new PluginOps(NoOp, null)
+
+ class Plugins {
+ def next: Plugins = null
+
+ def processIdent: PluginOp[Ident[T]] = NoOp
+ def processSelect: PluginOp[Select[T]] = NoOp
+
+ val IdentOps: PluginOps[Ident[T]] = NoOps
+ val SelectOps: PluginOps[Select[T]] = NoOps
+ }
+
+ val EmptyPlugin = new Plugins
+
+ private[this] var _plugins: Plugins = EmptyPlugin
+
+ override def plugins: Plugins = _plugins
+
+ class Plugin extends Plugins {
+ override val next = _plugins
+ _plugins = this
+
+ private def push[N <: Tree[T]](op: PluginOp[N], ops: => PluginOps[N]): PluginOps[N] =
+ if (op == NoOp) ops else new PluginOps(op, next)
+
+ override val IdentOps: PluginOps[Ident[T]] = push(processIdent, next.IdentOps)
+ override val SelectOps: PluginOps[Select[T]] = push(processSelect, next.SelectOps)
+ }
+
+ def postIdent(tree: Ident[T], old: Tree[T], c: Context, ops: PluginOps[Ident[T]]) =
+ if (ops eq NoOps) tree
+ else finishIdent(ops(tree, old, c), old, c, ops.next)
+
+ override def finishIdent(tree: Tree[T], old: Tree[T], c: Context, plugins: Plugins): Tree[T] = tree match {
+ case tree: Ident[_] => postIdent(tree, old, c, plugins.IdentOps)
+ case _ => postProcess(tree, old, c, plugins)
+ }
+
+ def postSelect(tree: Select[T], old: Tree[T], c: Context, ops: PluginOps[Select[T]]) =
+ if (ops eq NoOps) tree
+ else finishSelect(ops(tree, old, c), old, c, ops.next)
+
+ override def finishSelect(tree: Tree[T], old: Tree[T], c: Context, plugins: Plugins): Tree[T] = tree match {
+ case tree: Select[_] => postSelect(tree, old, c, plugins.SelectOps)
+ case _ => postProcess(tree, old, c, plugins)
+ }
+
+ protected def postProcess(tree: Tree[T], old: Tree[T], c: Context, plugins: Plugins): Tree[T] = tree match {
+ case tree: Ident[_] => finishIdent(tree, old, c, plugins)
+ case tree: Select[_] => finishSelect(tree, old, c, plugins)
+ }
+ }
+}
+
+import PluggableTransformers._, Types._, TypedTrees._
+
+class ExampleTransformer extends PluggableTransformer[Type] {
+
+ class ExamplePlugin extends Plugin {
+ override def processIdent = {
+ case tree @ Ident(x) if x.isTypeName => tree.derivedSelect(tree, x)
+ case tree => tree
+ }
+ override def processSelect = { tree =>
+ if (tree.isType) tree.derivedIdent(tree.name)
+ else EmptyTree
+ }
+ }
+
+} \ No newline at end of file
diff --git a/src/dotty/tools/dotc/core/SymDenotations.scala b/src/dotty/tools/dotc/core/SymDenotations.scala
index 79f2b7817..73d14141c 100644
--- a/src/dotty/tools/dotc/core/SymDenotations.scala
+++ b/src/dotty/tools/dotc/core/SymDenotations.scala
@@ -75,7 +75,7 @@ object SymDenotations {
private[this] var _flags: FlagSet = initFlags
/** The flag set */
- def flags: FlagSet = { ensureLoaded(); _flags }
+ def flags: FlagSet = { ensureCompleted(); _flags }
/** Update the flag set */
private[core] def flags_=(flags: FlagSet): Unit = { _flags = flags }
@@ -109,23 +109,14 @@ object SymDenotations {
// ----- completion ------------------------------
- // The following 4 members are overridden by instances of isLazy
-
- /** The denotation is loaded: flags and privateWithin are fully defined. */
- def isLoaded = true
+ // The following 2 members are overridden by instances of isLazy
/** The denotation is completed: all attributes are fully defined */
def isCompleted = true
- /** Try to load denotation. May throw `CyclicReference`. */
- protected[core] def tryLoad(): Unit = unsupported("tryLoad")
-
/** Try to complete denotation. May throw `CyclicReference`. */
protected[core] def tryComplete(): Unit = unsupported("tryComplete")
- /** Make sure denotation is loaded */
- final def ensureLoaded() = if (!isLoaded) tryLoad()
-
/** Make sure denotation is completed */
final def ensureCompleted() = if (!isCompleted) tryComplete()
@@ -544,14 +535,13 @@ object SymDenotations {
private[this] var _typeParams: List[TypeSymbol] = _
- /** The type parameters of this class. Loads the class but does not complete it. */
+ /** The type parameters of this class */
override final def typeParams(implicit ctx: Context): List[TypeSymbol] = {
val tparams = _typeParams
if (tparams != null) tparams else computeTypeParams
}
- /** The symbols defined in this class when the class is loaded but
- * not yet completed.
+ /** The symbols defined in this class when the class is not yet completed.
*/
protected def preCompleteDecls: Scope
@@ -892,8 +882,8 @@ object SymDenotations {
final def parents: List[TypeRef] = { if (_parents == null) tryComplete(); _parents }
def selfType: Type = { if (_selfType == null) tryComplete(); _selfType }
- final def preCompleteDecls = { if (_decls == null) tryLoad(); _decls }
- final def decls: Scope = { if (_parents == null) tryComplete(); _decls }
+ final def preCompleteDecls = { if (_decls == null) tryComplete(); _decls }
+ final def decls: Scope = { ensureCompleted(); _decls }
// cannot check on decls because decls might be != null even if class is not completed
final override def exists(implicit ctx: Context) = { ensureCompleted(); _parents != null }
@@ -922,66 +912,39 @@ object SymDenotations {
protected def completer: Completer[Denot]
protected def completer_= (c: Completer[Denot])
- override def isLoaded = _privateWithin != null
override def isCompleted = completer == null
- override protected[core] def tryLoad(): Unit =
- try {
- if (flags is Locked) throw new CyclicReference(symbol)
- setFlag(Locked)
- completer.load(this)
- } finally {
- flags &~= Locked
- }
-
override protected[core] def tryComplete(): Unit =
try {
if (flags is Locked) throw new CyclicReference(symbol)
setFlag(Locked)
val c = completer
+ if (c == null) throw new CompletionError(this)
completer = null // set completer to null to avoid space leaks
// and to make any subsequent completion attempt a CompletionError
- c.complete(this)
- } catch {
- case _: NullPointerException => throw new CompletionError(this)
+ c(this)
} finally {
flags &~= Locked
}
private[this] var _privateWithin: Symbol = _
- def privateWithin: Symbol = { if (_privateWithin == null) tryLoad(); _privateWithin }
+ def privateWithin: Symbol = { if (_privateWithin == null) tryComplete(); _privateWithin }
protected[core] def privateWithin_=(sym: Symbol): Unit = { _privateWithin = sym }
}
- abstract class Completer[Denot <: SymDenotation] extends DotClass {
- /** Load symbol, setting flags and privateWithin, and typeParams for classes
- * By default same as complete but can be overridden
- */
- def load(denot: Denot): Unit = complete(denot)
-
- /** Complete symbol, setting all its properties */
- def complete(denot: Denot): Unit
- }
-
+ /** When called, complete denotation, setting all its properties */
+ type Completer[Denot <: SymDenotation] = Denot => Unit
type SymCompleter = Completer[LazySymDenotation]
type ClassCompleter = Completer[LazyClassDenotation]
- class ModuleCompleter(cctx: CondensedContext) extends Completer[LazySymDenotation] {
+ class ModuleCompleter(cctx: CondensedContext) extends SymCompleter {
implicit protected def ctx: Context = cctx
- def classDenot(denot: LazySymDenotation) =
- denot.moduleClass.denot.asInstanceOf[LazyClassDenotation]
- def copyLoadedFields(denot: LazySymDenotation, from: LazyClassDenotation) = {
+ def apply(denot: LazySymDenotation): Unit = {
+ val from = denot.moduleClass.denot.asInstanceOf[LazyClassDenotation]
denot.setFlag(from.flags.toTermFlags & RetainedModuleFlags)
denot.privateWithin = from.privateWithin
- }
- def copyCompletedFields(denot: LazySymDenotation, from: LazyClassDenotation) = {
- copyLoadedFields(denot, from)
denot.annotations = from.annotations filter (_.appliesToModule)
}
- override def load(denot: LazySymDenotation): Unit =
- copyLoadedFields(denot, classDenot(denot))
- def complete(denot: LazySymDenotation): Unit =
- copyCompletedFields(denot, classDenot(denot))
}
/** A completer for missing references */
@@ -996,7 +959,7 @@ object SymDenotations {
denot.decls = EmptyScope
}
- def complete(denot: LazyClassDenotation): Unit = {
+ def apply(denot: LazyClassDenotation): Unit = {
val sym = denot.symbol
val file = denot.associatedFile
val (location, src) =
diff --git a/src/dotty/tools/dotc/core/SymbolLoaders.scala b/src/dotty/tools/dotc/core/SymbolLoaders.scala
index 8a5dd70d2..2e37d8124 100644
--- a/src/dotty/tools/dotc/core/SymbolLoaders.scala
+++ b/src/dotty/tools/dotc/core/SymbolLoaders.scala
@@ -164,7 +164,7 @@ abstract class SymbolLoader extends ClassCompleter {
*/
protected def description: String
- override def complete(root: LazyClassDenotation) = {
+ override def apply(root: LazyClassDenotation) = {
def signalError(ex: Exception) {
if (ctx.settings.debug.value) ex.printStackTrace()
val msg = ex.getMessage()
diff --git a/src/dotty/tools/dotc/core/Symbols.scala b/src/dotty/tools/dotc/core/Symbols.scala
index cd644df4e..68579f15f 100644
--- a/src/dotty/tools/dotc/core/Symbols.scala
+++ b/src/dotty/tools/dotc/core/Symbols.scala
@@ -19,6 +19,8 @@ import io.AbstractFile
/** Creation methods for symbols */
trait Symbols { this: Context =>
+// ---- Fundamental symbol creation methods ----------------------------------
+
def newLazySymbol[N <: Name](owner: Symbol, name: N, initFlags: FlagSet, completer: SymCompleter, coord: Coord = NoCoord) =
new Symbol(coord, new LazySymDenotation(_, owner, name, initFlags, completer)) {
type ThisName = N
@@ -45,9 +47,6 @@ trait Symbols { this: Context =>
(module, modcls)
}
- def newLazyPackageSymbols(owner: Symbol, name: TermName, completer: ClassCompleter) =
- newLazyModuleSymbols(owner, name, PackageCreationFlags, completer)
-
def newSymbol[N <: Name](owner: Symbol, name: N, flags: FlagSet, info: Type, privateWithin: Symbol = NoSymbol, coord: Coord = NoCoord) =
new Symbol(coord, CompleteSymDenotation(_, owner, name, flags, info, privateWithin)) {
type ThisName = N
@@ -90,13 +89,6 @@ trait Symbols { this: Context =>
(module, modcls)
}
- def newPackageSymbols(
- owner: Symbol,
- name: TermName,
- decls: Scope = newScope) =
- newModuleSymbols(
- owner, name, PackageCreationFlags, PackageCreationFlags, Nil, NoSymbol, decls)
-
def newStubSymbol(owner: Symbol, name: Name, file: AbstractFile = null): Symbol = {
def stub = new StubCompleter(ctx.condensed)
name match {
@@ -105,12 +97,55 @@ trait Symbols { this: Context =>
}
}
+// ---- Derived symbol creation methods -------------------------------------
+
+ def newLazyPackageSymbols(owner: Symbol, name: TermName, completer: ClassCompleter) =
+ newLazyModuleSymbols(owner, name, PackageCreationFlags, completer)
+
+ def newPackageSymbols(
+ owner: Symbol,
+ name: TermName,
+ decls: Scope = newScope) =
+ newModuleSymbols(
+ owner, name, PackageCreationFlags, PackageCreationFlags, Nil, NoSymbol, decls)
+
def newLocalDummy(cls: Symbol, coord: Coord = NoCoord) =
newSymbol(cls, nme.localDummyName(cls), EmptyFlags, NoType)
def newImportSymbol(expr: TypedTree, coord: Coord = NoCoord) =
newSymbol(NoSymbol, nme.IMPORT, EmptyFlags, ImportType(expr), coord = coord)
+ def newConstructor(cls: ClassSymbol, flags: FlagSet, paramNames: List[TermName], paramTypes: List[Type], privateWithin: Symbol = NoSymbol, coord: Coord = NoCoord) =
+ newSymbol(cls, nme.CONSTRUCTOR, flags, MethodType(paramNames, paramTypes)(_ => cls.typeConstructor), privateWithin, coord)
+
+ def newDefaultConstructor(cls: ClassSymbol) =
+ newConstructor(cls, EmptyFlags, Nil, Nil)
+
+ def newSelfSym(cls: ClassSymbol) =
+ ctx.newSymbol(cls, nme.THIS, SyntheticArtifact, cls.selfType)
+
+ /** Create new type parameters with given owner, names, and flags.
+ * @param boundsFn A function that, given type refs to the newly created
+ * parameters returns a list of their bounds.
+ */
+ def newTypeParams(
+ owner: Symbol,
+ names: List[TypeName],
+ flags: FlagSet,
+ boundsFn: List[TypeRef] => List[Type]) = {
+ lazy val tparams: List[TypeSymbol] = names map { name =>
+ newLazySymbol(owner, name, flags | TypeParam, { denot =>
+ denot.info = bounds(denot.symbol.asType)
+ })
+ }
+ lazy val bounds = (tparams zip boundsFn(tparams map (_.typeConstructor))).toMap
+ tparams
+ }
+
+ private val reverseApply = (x: TypeSymbol, f: TypeSymbol => TypeBounds) => f(x)
+
+// ----- Locating predefined symbols ----------------------------------------
+
def requiredPackage(path: PreName): TermSymbol =
base.staticRef(path.toTermName).requiredSymbol(_.isPackage).asTerm
diff --git a/src/dotty/tools/dotc/core/Trees.scala b/src/dotty/tools/dotc/core/Trees.scala
index 1245119f2..7d48641ee 100644
--- a/src/dotty/tools/dotc/core/Trees.scala
+++ b/src/dotty/tools/dotc/core/Trees.scala
@@ -41,7 +41,7 @@ object Trees {
/** The typeconstructor at the root of the tree */
type ThisTree[T] <: Tree[T]
- protected var _tpe: T = _
+ private var _tpe: T = _
/** The type of the tree. In case of an untyped tree,
* an UnAssignedTypeException is thrown.
@@ -51,6 +51,14 @@ object Trees {
_tpe
}
+ /** Copy `tpe` attribute from tree `from` into this tree, independently
+ * whether it is null or not.
+ */
+ def copyAttr(from: Tree[T]): ThisTree[T] = {
+ _tpe = from._tpe
+ this.asInstanceOf[ThisTree[T]]
+ }
+
/** Return a typed tree that's isomorphic to this tree, but has given
* type.
*/
@@ -58,7 +66,7 @@ object Trees {
val tree =
(if (_tpe == null ||
(_tpe.asInstanceOf[AnyRef] eq tpe.asInstanceOf[AnyRef])) this
- else clone).asInstanceOf[TypedTree]
+ else clone).asInstanceOf[Tree[Type]]
tree._tpe = tpe
tree.asInstanceOf[ThisTree[Type]]
}
@@ -80,6 +88,9 @@ object Trees {
/** Is this tree either the empty tree or the empty ValDef? */
def isEmpty: Boolean = false
+
+ override def hashCode(): Int = System.identityHashCode(this)
+ override def equals(that: Any) = this eq that.asInstanceOf[AnyRef]
}
class UnAssignedTypeException[T](tree: Tree[T]) extends RuntimeException {
@@ -368,7 +379,7 @@ object Trees {
/** >: lo <: hi */
case class TypeBoundsTree[T](lo: Tree[T], hi: Tree[T])(implicit cpos: Position)
- extends Tree[T] {
+ extends Tree[T] {
type ThisTree[T] = TypeBoundsTree[T]
val pos = cpos union lo.pos union hi.pos
}
@@ -490,8 +501,11 @@ object Trees {
def apply[T]: EmptyValDef[T] = theEmptyValDef.asInstanceOf
}
- /** A tree that can be shared without its position polluting containing trees */
- case class Shared[T](tree: Tree[T]) extends Tree[T] {
+ /** A tree that can be shared without its position
+ * polluting containing trees. Accumulators and tranformers
+ * memoize results of shared subtrees
+ */
+ case class Shared[T](shared: Tree[T]) extends Tree[T] {
type ThisTree[T] = Shared[T]
val pos = NoPosition
}
@@ -509,15 +523,382 @@ object Trees {
val pos = cpos union impl.pos
}
- abstract class TreeAccumulator[T, U] extends ((T, Tree[U]) => T) {
- def apply(x: T, tree: Tree[U]): T
- def foldOver(x: T, tree: Tree[U]): T = ???
- }
-
-// ----- Helper functions ---------------------------------------------
+// ----- Helper functions and classes ---------------------------------------
@tailrec final def unionPos(base: Position, trees: List[Tree[_]]): Position = trees match {
case t :: ts => unionPos(base union t.pos, ts)
case nil => base
}
-} \ No newline at end of file
+
+ implicit class TreeCopier[T](val tree: Tree[T]) extends AnyVal {
+ implicit def cpos = tree.pos
+ def derivedIdent(name: Name): Ident[T] = tree match {
+ case tree: Ident[_] if (name == tree.name) => tree
+ case _ => Ident(name).copyAttr(tree)
+ }
+ def derivedSelect(qualifier: Tree[T], name: Name): Select[T] = tree match {
+ case tree: Select[_] if (qualifier eq tree.qualifier) && (name == tree.name) => tree
+ case _ => Select(qualifier, name).copyAttr(tree)
+ }
+ def derivedThis(qual: TypeName): This[T] = tree match {
+ case tree: This[_] if (qual == tree.qual) => tree
+ case _ => This(qual).copyAttr(tree)
+ }
+ def derivedSuper(qual: Tree[T], mix: TypeName): Super[T] = tree match {
+ case tree: Super[_] if (qual eq tree.qual) && (mix == tree.mix) => tree
+ case _ => Super(qual, mix).copyAttr(tree)
+ }
+ def derivedApply(fun: Tree[T], args: List[Tree[T]]): Apply[T] = tree match {
+ case tree: Apply[_] if (fun eq tree.fun) && (args eq tree.args) => tree
+ case _ => Apply(fun, args).copyAttr(tree)
+ }
+ def derivedTypeApply(fun: Tree[T], args: List[Tree[T]]): TypeApply[T] = tree match {
+ case tree: TypeApply[_] if (fun eq tree.fun) && (args eq tree.args) => tree
+ case _ => TypeApply(fun, args).copyAttr(tree)
+ }
+ def derivedLiteral(const: Constant): Literal[T] = tree match {
+ case tree: Literal[_] if (const == tree.const) => tree
+ case _ => Literal(const).copyAttr(tree)
+ }
+ def derivedNew(tpt: Tree[T]): New[T] = tree match {
+ case tree: New[_] if (tpt eq tree.tpt) => tree
+ case _ => New(tpt).copyAttr(tree)
+ }
+ def derivedPair(left: Tree[T], right: Tree[T]): Pair[T] = tree match {
+ case tree: Pair[_] if (left eq tree.left) && (right eq tree.right) => tree
+ case _ => Pair(left, right).copyAttr(tree)
+ }
+ def derivedTyped(expr: Tree[T], tpt: Tree[T]): Typed[T] = tree match {
+ case tree: Typed[_] if (expr eq tree.expr) && (tpt eq tree.tpt) => tree
+ case _ => Typed(expr, tpt).copyAttr(tree)
+ }
+ def derivedNamedArg(name: Name, arg: Tree[T]): NamedArg[T] = tree match {
+ case tree: NamedArg[_] if (name == tree.name) && (arg eq tree.arg) => tree
+ case _ => NamedArg(name, arg).copyAttr(tree)
+ }
+ def derivedAssign(lhs: Tree[T], rhs: Tree[T]): Assign[T] = tree match {
+ case tree: Assign[_] if (lhs eq tree.lhs) && (rhs eq tree.rhs) => tree
+ case _ => Assign(lhs, rhs).copyAttr(tree)
+ }
+ def derivedFunction(vparams: List[ValDef[T]], body: Tree[T]): Function[T] = tree match {
+ case tree: Function[_] if (vparams eq tree.vparams) && (body eq tree.body) => tree
+ case _ => Function(vparams, body).copyAttr(tree)
+ }
+ def derivedBlock(stats: List[Tree[T]], expr: Tree[T]): Block[T] = tree match {
+ case tree: Block[_] if (stats eq tree.stats) && (expr eq tree.expr) => tree
+ case _ => Block(stats, expr).copyAttr(tree)
+ }
+ def derivedIf(cond: Tree[T], thenp: Tree[T], elsep: Tree[T]): If[T] = tree match {
+ case tree: If[_] if (cond eq tree.cond) && (thenp eq tree.thenp) && (elsep eq tree.elsep) => tree
+ case _ => If(cond, thenp, elsep).copyAttr(tree)
+ }
+ def derivedMatch(selector: Tree[T], cases: List[CaseDef[T]]): Match[T] = tree match {
+ case tree: Match[_] if (selector eq tree.selector) && (cases eq tree.cases) => tree
+ case _ => Match(selector, cases).copyAttr(tree)
+ }
+ def derivedCaseDef(pat: Tree[T], guard: Tree[T], body: Tree[T]): CaseDef[T] = tree match {
+ case tree: CaseDef[_] if (pat eq tree.pat) && (guard eq tree.guard) && (body eq tree.body) => tree
+ case _ => CaseDef(pat, guard, body).copyAttr(tree)
+ }
+ def derivedReturn(expr: Tree[T], from: Ident[T]): Return[T] = tree match {
+ case tree: Return[_] if (expr eq tree.expr) && (from eq tree.from) => tree
+ case _ => Return(expr, from).copyAttr(tree)
+ }
+ def derivedTry(block: Tree[T], catches: List[CaseDef[T]], finalizer: Tree[T]): Try[T] = tree match {
+ case tree: Try[_] if (block eq tree.block) && (catches eq tree.catches) && (finalizer eq tree.finalizer) => tree
+ case _ => Try(block, catches, finalizer).copyAttr(tree)
+ }
+ def derivedThrow(expr: Tree[T]): Throw[T] = tree match {
+ case tree: Throw[_] if (expr eq tree.expr) => tree
+ case _ => Throw(expr).copyAttr(tree)
+ }
+ def derivedArrayValue(elemtpt: Tree[T], elems: List[Tree[T]]): ArrayValue[T] = tree match {
+ case tree: ArrayValue[_] if (elemtpt eq tree.elemtpt) && (elems eq tree.elems) => tree
+ case _ => ArrayValue(elemtpt, elems).copyAttr(tree)
+ }
+ def derivedTypeTree(original: Tree[T] = EmptyTree[T]): TypeTree[T] = tree match {
+ case tree: TypeTree[_] if (original eq tree.original) => tree
+ case _ => TypeTree(original).copyAttr(tree)
+ }
+ def derivedSingletonTypeTree(ref: Tree[T]): SingletonTypeTree[T] = tree match {
+ case tree: SingletonTypeTree[_] if (ref eq tree.ref) => tree
+ case _ => SingletonTypeTree(ref).copyAttr(tree)
+ }
+ def derivedSelectFromTypeTree(qualifier: Tree[T], name: TypeName): SelectFromTypeTree[T] = tree match {
+ case tree: SelectFromTypeTree[_] if (qualifier eq tree.qualifier) && (name == tree.name) => tree
+ case _ => SelectFromTypeTree(qualifier, name).copyAttr(tree)
+ }
+ def derivedAndTypeTree(left: Tree[T], right: Tree[T]): AndTypeTree[T] = tree match {
+ case tree: AndTypeTree[_] if (left eq tree.left) && (right eq tree.right) => tree
+ case _ => AndTypeTree(left, right).copyAttr(tree)
+ }
+ def derivedOrTypeTree(left: Tree[T], right: Tree[T]): OrTypeTree[T] = tree match {
+ case tree: OrTypeTree[_] if (left eq tree.left) && (right eq tree.right) => tree
+ case _ => OrTypeTree(left, right).copyAttr(tree)
+ }
+ def derivedRefineTypeTree(tpt: Tree[T], refinements: List[DefTree[T]]): RefineTypeTree[T] = tree match {
+ case tree: RefineTypeTree[_] if (tpt eq tree.tpt) && (refinements eq tree.refinements) => tree
+ case _ => RefineTypeTree(tpt, refinements).copyAttr(tree)
+ }
+ def derivedAppliedTypeTree(tpt: Tree[T], args: List[Tree[T]]): AppliedTypeTree[T] = tree match {
+ case tree: AppliedTypeTree[_] if (tpt eq tree.tpt) && (args eq tree.args) => tree
+ case _ => AppliedTypeTree(tpt, args).copyAttr(tree)
+ }
+ def derivedTypeBoundsTree(lo: Tree[T], hi: Tree[T]): TypeBoundsTree[T] = tree match {
+ case tree: TypeBoundsTree[_] if (lo eq tree.lo) && (hi eq tree.hi) => tree
+ case _ => TypeBoundsTree(lo, hi).copyAttr(tree)
+ }
+ def derivedBind(name: Name, body: Tree[T]): Bind[T] = tree match {
+ case tree: Bind[_] if (name eq tree.name) && (body eq tree.body) => tree
+ case _ => Bind(name, body).copyAttr(tree)
+ }
+ def derivedAlternative(trees: List[Tree[T]]): Alternative[T] = tree match {
+ case tree: Alternative[_] if (trees eq tree.trees) => tree
+ case _ => Alternative(trees).copyAttr(tree)
+ }
+ def derivedUnApply(fun: Tree[T], args: List[Tree[T]]): UnApply[T] = tree match {
+ case tree: UnApply[_] if (fun eq tree.fun) && (args eq tree.args) => tree
+ case _ => UnApply(fun, args).copyAttr(tree)
+ }
+ def derivedValDef(mods: Modifiers[T], name: Name, tpt: Tree[T], rhs: Tree[T]): ValDef[T] = tree match {
+ case tree: ValDef[_] if (mods == tree.mods) && (name == tree.name) && (tpt eq tree.tpt) && (rhs eq tree.rhs) => tree
+ case _ => ValDef(mods, name, tpt, rhs).copyAttr(tree)
+ }
+ def derivedDefDef(mods: Modifiers[T], name: Name, tparams: List[TypeDef[T]], vparamss: List[List[ValDef[T]]], tpt: Tree[T], rhs: Tree[T]): DefDef[T] = tree match {
+ case tree: DefDef[_] if (mods == tree.mods) && (name == tree.name) && (tparams eq tree.tparams) && (vparamss eq tree.vparamss) && (tpt eq tree.tpt) && (rhs eq tree.rhs) => tree
+ case _ => DefDef(mods, name, tparams, vparamss, tpt, rhs).copyAttr(tree)
+ }
+ def derivedTypeDef(mods: Modifiers[T], name: Name, rhs: Tree[T]): TypeDef[T] = tree match {
+ case tree: TypeDef[_] if (mods == tree.mods) && (name == tree.name) && (rhs eq tree.rhs) => tree
+ case _ => TypeDef(mods, name, rhs).copyAttr(tree)
+ }
+ def derivedTemplate(parents: List[Tree[T]], self: ValDef[T], body: List[Tree[T]]): Template[T] = tree match {
+ case tree: Template[_] if (parents eq tree.parents) && (self eq tree.self) && (body eq tree.body) => tree
+ case _ => Template(parents, self, body).copyAttr(tree)
+ }
+ def derivedClassDef(mods: Modifiers[T], name: TypeName, tparams: List[TypeDef[T]], impl: Template[T]): ClassDef[T] = tree match {
+ case tree: ClassDef[_] if (mods == tree.mods) && (name == tree.name) && (tparams eq tree.tparams) && (impl eq tree.impl) => tree
+ case _ => ClassDef(mods, name, tparams, impl).copyAttr(tree)
+ }
+ def derivedImport(expr: Tree[T], selectors: List[UntypedTree]): Import[T] = tree match {
+ case tree: Import[_] if (expr eq tree.expr) && (selectors eq tree.selectors) => tree
+ case _ => Import(expr, selectors).copyAttr(tree)
+ }
+ def derivedPackageDef(pid: RefTree[T], stats: List[Tree[T]]): PackageDef[T] = tree match {
+ case tree: PackageDef[_] if (pid eq tree.pid) && (stats eq tree.stats) => tree
+ case _ => PackageDef(pid, stats).copyAttr(tree)
+ }
+ def derivedAnnotated(annot: Tree[T], arg: Tree[T]): Annotated[T] = tree match {
+ case tree: Annotated[_] if (annot eq tree.annot) && (arg eq tree.arg) => tree
+ case _ => Annotated(annot, arg).copyAttr(tree)
+ }
+ def derivedShared(shared: Tree[T]): Shared[T] = tree match {
+ case tree: Shared[_] if (shared eq tree.shared) => tree
+ case _ => Shared(shared).copyAttr(tree)
+ }
+ }
+
+ abstract class TreeTransformer[T, C] {
+ var sharedMemo: Map[Shared[T], Shared[T]] = Map()
+ type Plugins >: Null
+ def plugins: Plugins = null
+ def finishIdent(tree: Tree[T], old: Tree[T], c: C, plugins: Plugins) = tree
+ def finishSelect(tree: Tree[T], old: Tree[T], c: C, plugins: Plugins) = tree
+ def transform(tree: Tree[T], c: C): Tree[T] = tree match {
+ case Ident(name) =>
+ finishIdent(tree, tree, c, plugins)
+ case Select(qualifier, name) =>
+ finishSelect(tree.derivedSelect(transform(qualifier, c), name), tree, c, plugins)
+ case This(qual) =>
+ tree
+ case Super(qual, mix) =>
+ tree.derivedSuper(transform(qual, c), mix)
+ case Apply(fun, args) =>
+ tree.derivedApply(transform(fun, c), transform(args, c))
+ case TypeApply(fun, args) =>
+ tree.derivedTypeApply(transform(fun, c), transform(args, c))
+ case Literal(const) =>
+ tree
+ case New(tpt) =>
+ tree.derivedNew(transform(tpt, c))
+ case Pair(left, right) =>
+ tree.derivedPair(transform(left, c), transform(right, c))
+ case Typed(expr, tpt) =>
+ tree.derivedTyped(transform(expr, c), transform(tpt, c))
+ case NamedArg(name, arg) =>
+ tree.derivedNamedArg(name, transform(arg, c))
+ case Assign(lhs, rhs) =>
+ tree.derivedAssign(transform(lhs, c), transform(rhs, c))
+ case Function(vparams, body) =>
+ tree.derivedFunction(transformSub(vparams, c), transform(body, c))
+ case Block(stats, expr) =>
+ tree.derivedBlock(transform(stats, c), transform(expr, c))
+ case If(cond, thenp, elsep) =>
+ tree.derivedIf(transform(cond, c), transform(thenp, c), transform(elsep, c))
+ case Match(selector, cases) =>
+ tree.derivedMatch(transform(selector, c), transformSub(cases, c))
+ case CaseDef(pat, guard, body) =>
+ tree.derivedCaseDef(transform(pat, c), transform(guard, c), transform(body, c))
+ case Return(expr, from) =>
+ tree.derivedReturn(transform(expr, c), transformSub(from, c))
+ case Try(block, catches, finalizer) =>
+ tree.derivedTry(transform(block, c), transformSub(catches, c), transform(finalizer, c))
+ case Throw(expr) =>
+ tree.derivedThrow(transform(expr, c))
+ case ArrayValue(elemtpt, elems) =>
+ tree.derivedArrayValue(transform(elemtpt, c), transform(elems, c))
+ case TypeTree(original) =>
+ tree.derivedTypeTree(transform(original, c))
+ case SingletonTypeTree(ref) =>
+ tree.derivedSingletonTypeTree(transform(ref, c))
+ case SelectFromTypeTree(qualifier, name) =>
+ tree.derivedSelectFromTypeTree(transform(qualifier, c), name)
+ case AndTypeTree(left, right) =>
+ tree.derivedAndTypeTree(transform(left, c), transform(right, c))
+ case OrTypeTree(left, right) =>
+ tree.derivedOrTypeTree(transform(left, c), transform(right, c))
+ case RefineTypeTree(tpt, refinements) =>
+ tree.derivedRefineTypeTree(transform(tpt, c), transformSub(refinements, c))
+ case AppliedTypeTree(tpt, args) =>
+ tree.derivedAppliedTypeTree(transform(tpt, c), transform(args, c))
+ case TypeBoundsTree(lo, hi) =>
+ tree.derivedTypeBoundsTree(transform(lo, c), transform(hi, c))
+ case Bind(name, body) =>
+ tree.derivedBind(name, transform(body, c))
+ case Alternative(trees) =>
+ tree.derivedAlternative(transform(trees, c))
+ case UnApply(fun, args) =>
+ tree.derivedUnApply(transform(fun, c), transform(args, c))
+ case ValDef(mods, name, tpt, rhs) =>
+ tree.derivedValDef(mods, name, transform(tpt, c), transform(rhs, c))
+ case DefDef(mods, name, tparams, vparamss, tpt, rhs) =>
+ tree.derivedDefDef(mods, name, transformSub(tparams, c), vparamss mapConserve (transformSub(_, c)), transform(tpt, c), transform(rhs, c))
+ case TypeDef(mods, name, rhs) =>
+ tree.derivedTypeDef(mods, name, transform(rhs, c))
+ case Template(parents, self, body) =>
+ tree.derivedTemplate(transform(parents, c), transformSub(self, c), transform(body, c))
+ case ClassDef(mods, name, tparams, impl) =>
+ tree.derivedClassDef(mods, name, transformSub(tparams, c), transformSub(impl, c))
+ case Import(expr, selectors) =>
+ tree.derivedImport(transform(expr, c), selectors)
+ case PackageDef(pid, stats) =>
+ tree.derivedPackageDef(transformSub(pid, c), transform(stats, c))
+ case Annotated(annot, arg) =>
+ tree.derivedAnnotated(transform(annot, c), transform(arg, c))
+ case EmptyTree() =>
+ tree
+ case tree @ Shared(shared) =>
+ sharedMemo get tree match {
+ case Some(tree1) => tree1
+ case None =>
+ val tree1 = tree.derivedShared(transform(shared, c))
+ sharedMemo = sharedMemo.updated(tree, tree1)
+ tree1
+ }
+ }
+ def transform(trees: List[Tree[T]], c: C): List[Tree[T]] =
+ trees mapConserve (transform(_, c))
+ def transformSub(tree: Tree[T], c: C): tree.ThisTree[T] =
+ transform(tree, c).asInstanceOf[tree.ThisTree[T ]]
+ def transformSub[TT <: Tree[T]](trees: List[TT], c: C): List[TT] =
+ (trees mapConserve (transformSub(_, c))).asInstanceOf[List[TT]]
+ }
+
+ abstract class TreeAccumulator[T, U] extends ((T, Tree[U]) => T) {
+ var sharedMemo: Map[Shared[U], T] = Map()
+ def apply(x: T, tree: Tree[U]): T
+ def apply(x: T, trees: List[Tree[U]]): T = (x /: trees)(apply)
+ def foldOver(x: T, tree: Tree[U]): T = tree match {
+ case Ident(name) =>
+ x
+ case Select(qualifier, name) =>
+ this(x, qualifier)
+ case This(qual) =>
+ x
+ case Super(qual, mix) =>
+ this(x, qual)
+ case Apply(fun, args) =>
+ this(this(x, fun), args)
+ case TypeApply(fun, args) =>
+ this(this(x, fun), args)
+ case Literal(const) =>
+ x
+ case New(tpt) =>
+ this(x, tpt)
+ case Pair(left, right) =>
+ this(this(x, left), right)
+ case Typed(expr, tpt) =>
+ this(this(x, expr), tpt)
+ case NamedArg(name, arg) =>
+ this(x, arg)
+ case Assign(lhs, rhs) =>
+ this(this(x, lhs), rhs)
+ case Function(vparams, body) =>
+ this(this(x, vparams), body)
+ case Block(stats, expr) =>
+ this(this(x, stats), expr)
+ case If(cond, thenp, elsep) =>
+ this(this(this(x, cond), thenp), elsep)
+ case Match(selector, cases) =>
+ this(this(x, selector), cases)
+ case CaseDef(pat, guard, body) =>
+ this(this(this(x, pat), guard), body)
+ case Return(expr, from) =>
+ this(this(x, expr), from)
+ case Try(block, catches, finalizer) =>
+ this(this(this(x, block), catches), finalizer)
+ case Throw(expr) =>
+ this(x, expr)
+ case ArrayValue(elemtpt, elems) =>
+ this(this(x, elemtpt), elems)
+ case TypeTree(original) =>
+ x
+ case SingletonTypeTree(ref) =>
+ this(x, ref)
+ case SelectFromTypeTree(qualifier, name) =>
+ this(x, qualifier)
+ case AndTypeTree(left, right) =>
+ this(this(x, left), right)
+ case OrTypeTree(left, right) =>
+ this(this(x, left), right)
+ case RefineTypeTree(tpt, refinements) =>
+ this(this(x, tpt), refinements)
+ case AppliedTypeTree(tpt, args) =>
+ this(this(x, tpt), args)
+ case TypeBoundsTree(lo, hi) =>
+ this(this(x, lo), hi)
+ case Bind(name, body) =>
+ this(x, body)
+ case Alternative(trees) =>
+ this(x, trees)
+ case UnApply(fun, args) =>
+ this(this(x, fun), args)
+ case ValDef(mods, name, tpt, rhs) =>
+ this(this(x, tpt), rhs)
+ case DefDef(mods, name, tparams, vparamss, tpt, rhs) =>
+ this(this((this(x, tparams) /: vparamss)(apply), tpt), rhs)
+ case TypeDef(mods, name, rhs) =>
+ this(x, rhs)
+ case Template(parents, self, body) =>
+ this(this(this(x, parents), self), body)
+ case ClassDef(mods, name, tparams, impl) =>
+ this(this(x, tparams), impl)
+ case Import(expr, selectors) =>
+ this(x, expr)
+ case PackageDef(pid, stats) =>
+ this(this(x, pid), stats)
+ case Annotated(annot, arg) =>
+ this(this(x, annot), arg)
+ case EmptyTree() =>
+ x
+ case tree @ Shared(shared) =>
+ sharedMemo get tree match {
+ case Some(x1) => x1
+ case None =>
+ val x1 = this(x, shared)
+ sharedMemo = sharedMemo.updated(tree, x1)
+ x1
+ }
+ }
+ }
+}
diff --git a/src/dotty/tools/dotc/core/TypedTreeGen.scala b/src/dotty/tools/dotc/core/TypedTreeGen.scala
deleted file mode 100644
index 7672f1f77..000000000
--- a/src/dotty/tools/dotc/core/TypedTreeGen.scala
+++ /dev/null
@@ -1,236 +0,0 @@
-package dotty.tools.dotc
-package core
-
-import Trees._, Positions._, Types._, Contexts._, Constants._, Names._, Flags._
-import SymDenotations._, Symbols._, StdNames._, Annotations._
-
-object TypedTrees {
-
- class TypeTreeGen {
- implicit def pos(implicit ctx: Context): Position = ctx.position
-
- def defPos(sym: Symbol)(implicit ctx: Context) = ctx.position union sym.coord.toPosition
-
- def Modifiers(sym: Symbol)(implicit ctx: Context): Modifiers[Type] = Trees.Modifiers[Type](
- sym.flags & ModifierFlags,
- if (sym.privateWithin.exists) sym.privateWithin.asType.name else tpnme.EMPTY,
- sym.annotations map (_.tree))
-
- def Ident(tp: NamedType)(implicit ctx: Context): Ident[Type] =
- Trees.Ident(tp.name).withType(tp)
-
- def Select(pre: TypedTree, tp: NamedType)(implicit ctx: Context): Select[Type] =
- Trees.Select(pre, tp.name).withType(tp)
-
- def This(cls: ClassSymbol)(implicit ctx: Context): This[Type] =
- Trees.This(cls.name).withType(cls.thisType)
-
- def Super(qual: TypedTree, mixin: Symbol = NoSymbol)(implicit ctx: Context): Super[Type] = {
- val cls = qual.tpe.typeSymbol
- val (owntype, mix) =
- if (mixin.exists) (mixin.typeConstructor, mixin.asType.name)
- else (ctx.glb(cls.info.parents), tpnme.EMPTY)
- Trees.Super(qual, mix).withType(SuperType(qual.tpe, owntype))
- }
-
- def Apply(fn: TypedTree, args: List[TypedTree])(implicit ctx: Context): Apply[Type] = {
- val fntpe @ MethodType(pnames, ptypes) = fn.tpe
- assert(sameLength(ptypes, args))
- Trees.Apply(fn, args).withType(fntpe.instantiate(args map (_.tpe)))
- }
-
- def TypeApply(fn: TypedTree, args: List[TypedTree])(implicit ctx: Context): TypeApply[Type] = {
- val fntpe @ PolyType(pnames) = fn.tpe
- assert(sameLength(pnames, args))
- Trees.TypeApply(fn, args).withType(fntpe.instantiate(args map (_.tpe)))
- }
-
- def Literal(const: Constant)(implicit ctx: Context): Literal[Type] =
- Trees.Literal(const).withType(const.tpe)
-
- def New(tp: Type)(implicit ctx: Context): New[Type] =
- Trees.New(TypeTree(tp))
-
- def Pair(left: TypedTree, right: TypedTree)(implicit ctx: Context): Pair[Type] =
- Trees.Pair(left, right).withType(defn.PairType.appliedTo(left.tpe, right.tpe))
-
- def Typed(expr: TypedTree, tpt: TypedTree)(implicit ctx: Context): Typed[Type] =
- Trees.Typed(expr, tpt).withType(tpt.tpe)
-
- def NamedArg[Type](name: Name, arg: TypedTree)(implicit ctx: Context) =
- Trees.NamedArg(name, arg).withType(arg.tpe)
-
- def Assign(lhs: TypedTree, rhs: TypedTree)(implicit ctx: Context): Assign[Type] =
- Trees.Assign(lhs, rhs).withType(defn.UnitType)
-
- def Function(vparams: List[ValDef[Type]], body: TypedTree)(implicit ctx: Context): Function[Type] =
- Trees.Function(vparams, body)
- .withType(defn.FunctionType(vparams map (_.tpt.tpe), body.tpe))
-
- def Block(stats: List[TypedTree], expr: TypedTree)(implicit ctx: Context): Block[Type] =
- Trees.Block(stats, expr).withType(expr.tpe) // !!! need to make sure that type does not refer to locals
-
- def If(cond: TypedTree, thenp: TypedTree, elsep: TypedTree)(implicit ctx: Context): If[Type] =
- Trees.If(cond, thenp, elsep).withType(thenp.tpe | elsep.tpe)
-
- def Match(selector: TypedTree, cases: List[CaseDef[Type]])(implicit ctx: Context): Match[Type] =
- Trees.Match(selector, cases).withType(ctx.lub(cases map (_.body.tpe)))
-
- def CaseDef(pat: TypedTree, guard: TypedTree, body: TypedTree)(implicit ctx: Context): CaseDef[Type] =
- Trees.CaseDef(pat, guard, body).withType(body.tpe)
-
- def Return(expr: TypedTree, from: Ident[Type])(implicit ctx: Context): Return[Type] =
- Trees.Return(expr, from).withType(defn.NothingType)
-
- def Throw(expr: TypedTree)(implicit ctx: Context): Throw[Type] =
- Trees.Throw(expr).withType(defn.NothingType)
-
- def ArrayValue(elemtpt: TypedTree, elems: List[TypedTree])(implicit ctx: Context): ArrayValue[Type] =
- Trees.ArrayValue(elemtpt, elems).withType(defn.ArrayType.appliedTo(elemtpt.tpe))
-
- def TypeTree(tp: Type, original: TypedTree = EmptyTree)(implicit ctx: Context): TypeTree[Type] =
- Trees.TypeTree(original).withType(tp)
-
- def SingletonTypeTree(ref: TypedTree)(implicit ctx: Context): SingletonTypeTree[Type] =
- Trees.SingletonTypeTree(ref).withType(ref.tpe)
-
- def SelectFromTypeTree(qualifier: TypedTree, name: TypeName)(implicit ctx: Context): SelectFromTypeTree[Type] =
- Trees.SelectFromTypeTree(qualifier, name).withType(TypeRef(qualifier.tpe, name))
-
- def AndTypeTree(left: TypedTree, right: TypedTree)(implicit ctx: Context): AndTypeTree[Type] =
- Trees.AndTypeTree(left, right).withType(left.tpe & right.tpe)
-
- def OrTypeTree(left: TypedTree, right: TypedTree)(implicit ctx: Context): OrTypeTree[Type] =
- Trees.OrTypeTree(left, right).withType(left.tpe | right.tpe)
-
- def RefineTypeTree(tpt: TypedTree, refinements: List[DefTree[Type]])(implicit ctx: Context): RefineTypeTree[Type] = {
- def refineType(tp: Type, refinement: Symbol): Type =
- RefinedType(tp, refinement.name, refinement.info)
- Trees.RefineTypeTree(tpt, refinements)
- .withType((tpt.tpe /: (refinements map (_.symbol)))(refineType))
- }
-
- def refineType(tp: Type, refinement: Symbol)(implicit ctx: Context): Type =
- RefinedType(tp, refinement.name, refinement.info)
-
- def AppliedTypeTree(tpt: TypedTree, args: List[TypedTree])(implicit ctx: Context): AppliedTypeTree[Type] =
- Trees.AppliedTypeTree(tpt, args).withType(tpt.tpe.appliedTo(args map (_.tpe)))
-
- def TypeBoundsTree(lo: TypedTree, hi: TypedTree)(implicit ctx: Context): TypeBoundsTree[Type] =
- Trees.TypeBoundsTree(lo, hi).withType(TypeBounds(lo.tpe, hi.tpe))
-
- def Bind(sym: Symbol, body: TypedTree)(implicit ctx: Context): Bind[Type] =
- Trees.Bind(sym.name, body)(defPos(sym)).withType(sym.info)
-
- def Alternative(trees: List[TypedTree])(implicit ctx: Context): Alternative[Type] =
- Trees.Alternative(trees).withType(ctx.lub(trees map (_.tpe)))
-
- def UnApply(fun: TypedTree, args: List[TypedTree])(implicit ctx: Context): UnApply[Type] =
- Trees.UnApply(fun, args).withType(fun.tpe match {
- case MethodType(_, paramTypes) => paramTypes.head
- })
-
- def refType(sym: Symbol)(implicit ctx: Context) = NamedType(sym.owner.thisType, sym)
-
- def ValDef(sym: TermSymbol, rhs: TypedTree = EmptyTree)(implicit ctx: Context): ValDef[Type] =
- Trees.ValDef(Modifiers(sym), sym.name, TypeTree(sym.info), rhs)(defPos(sym))
- .withType(refType(sym))
-
- def DefDef(sym: TermSymbol, rhs: TypedTree = EmptyTree)(implicit ctx: Context): DefDef[Type] = {
-
- val (tparams, mtp) = sym.info match {
- case tp: PolyType =>
- val paramBounds = (tp.paramNames zip tp.paramBounds).toMap
- def typeParam(name: TypeName): TypeSymbol =
- ctx.newLazySymbol(sym, name, TypeParam, typeParamCompleter)
- def typeParamCompleter = new SymCompleter {
- def complete(denot: LazySymDenotation) =
- denot.info = new InstPolyMap(tp, tparamRefs) apply
- paramBounds(denot.symbol.asType.name)
- }
- lazy val tparams = tp.paramNames map typeParam
- lazy val tparamRefs = tparams map (_.typeConstructor)
- (tparams, tp.instantiate(tparamRefs))
- case tp => (Nil, tp)
- }
-
- def valueParamss(tp: Type): (List[List[TermSymbol]], Type) = tp match {
- case tp @ MethodType(paramNames, paramTypes) =>
- def valueParam(name: TermName, info: Type): TermSymbol =
- ctx.newSymbol(sym, name, TermParam, info)
- val params = (paramNames, paramTypes).zipped.map(valueParam)
- val (paramss, rtp) = valueParamss(tp.instantiate(params map (_.typeConstructor)))
- (params :: paramss, rtp)
- case tp => (Nil, tp)
- }
- val (vparamss, rtp) = valueParamss(mtp)
-
- Trees.DefDef(
- Modifiers(sym), sym.name, tparams map TypeDef,
- vparamss map (_ map (ValDef(_))), TypeTree(rtp), rhs)(defPos(sym))
- .withType(refType(sym))
- }
-
- def TypeDef(sym: TypeSymbol)(implicit ctx: Context): TypeDef[Type] =
- Trees.TypeDef(Modifiers(sym), sym.name, TypeTree(sym.info))(defPos(sym))
- .withType(refType(sym))
-
- def ClassDef(cls: ClassSymbol, typeParams: List[TypeSymbol], body: List[TypedTree])(implicit ctx: Context): ClassDef[Type] = {
- val parents = cls.info.parents map (TypeTree(_))
- val selfType =
- if (cls.selfType eq cls.typeConstructor) EmptyValDef
- else ValDef(ctx.newSymbol(cls, nme.THIS, SyntheticArtifact, cls.selfType))
- def isOwnTypeParamAccessor(stat: TypedTree) =
- stat.symbol.owner == cls && (stat.symbol is TypeParam)
- val (tparamAccessors, rest) = body partition isOwnTypeParamAccessor
- val tparams =
- (typeParams map TypeDef) ++
- (tparamAccessors collect {
- case td: TypeDef[_] if !(typeParams contains td.symbol) => td
- })
- val findLocalDummy = new FindLocalDummyAccumulator(cls)
- val localDummy = ((NoSymbol: Symbol) /: body)(findLocalDummy)
- .orElse(ctx.newLocalDummy(cls))
- val impl = Trees.Template(parents, selfType, rest)
- .withType(refType(localDummy))
- Trees.ClassDef(Modifiers(cls), cls.name, tparams, impl)(defPos(cls))
- .withType(refType(cls))
- }
-
- def Import(expr: TypedTree, selectors: List[UntypedTree])(implicit ctx: Context): Import[Type] =
- Trees.Import(expr, selectors).withType(refType(ctx.newImportSymbol(expr)))
-
- def PackageDef(pid: RefTree[Type], stats: List[TypedTree])(implicit ctx: Context): PackageDef[Type] =
- Trees.PackageDef(pid, stats).withType(refType(pid.symbol))
-
- def Annotated(annot: TypedTree, arg: TypedTree)(implicit ctx: Context): Annotated[Type] =
- Trees.Annotated(annot, arg).withType(AnnotatedType(List(Annotation(annot)), arg.tpe))
-
- def EmptyTree: TypedTree = Trees.EmptyTree[Type]
-
- def EmptyValDef: ValDef[Type] = Trees.EmptyValDef[Type]
-
- // ----------------------------------------------------------
-
- def New(tp: Type, args: List[TypedTree])(implicit ctx: Context): Apply[Type] =
- Apply(
- Select(
- New(tp),
- TermRef(tp.normalizedPrefix, tp.typeSymbol.primaryConstructor.asTerm)),
- args)
- }
-
- object tpd extends TypeTreeGen
-
- class FindLocalDummyAccumulator(cls: ClassSymbol)(implicit ctx: Context) extends TreeAccumulator[Symbol, Type] {
- def apply(sym: Symbol, tree: TypedTree) =
- if (sym.exists) sym
- else if (tree.isDef) {
- val owner = tree.symbol.owner
- if (owner.isLocalDummy && owner.owner == cls) owner
- else if (owner == cls) foldOver(sym, tree)
- else sym
- } else foldOver(sym, tree)
- }
-}
-
diff --git a/src/dotty/tools/dotc/core/TypedTrees.scala b/src/dotty/tools/dotc/core/TypedTrees.scala
new file mode 100644
index 000000000..c8e468107
--- /dev/null
+++ b/src/dotty/tools/dotc/core/TypedTrees.scala
@@ -0,0 +1,293 @@
+package dotty.tools.dotc
+package core
+
+import Positions._, Types._, Contexts._, Constants._, Names._, Flags._
+import SymDenotations._, Symbols._, StdNames._, Annotations._
+
+object TypedTrees {
+
+ type Modifiers = Trees.Modifiers[Type]
+ type Tree = Trees.Tree[Type]
+ type TypTree = Trees.TypTree[Type]
+ type TermTree = Trees.TermTree[Type]
+ type SymTree = Trees.SymTree[Type]
+ type ProxyTree = Trees.ProxyTree[Type]
+ type NameTree = Trees.NameTree[Type]
+ type RefTree = Trees.RefTree[Type]
+ type DefTree = Trees.DefTree[Type]
+
+ type TreeCopier = Trees.TreeCopier[Type]
+ type TreeAccumulator[T] = Trees.TreeAccumulator[T, Type]
+ type TreeTransformer[C] = Trees.TreeTransformer[Type, C]
+
+ type Ident = Trees.Ident[Type]
+ type Select = Trees.Select[Type]
+ type This = Trees.This[Type]
+ type Super = Trees.Super[Type]
+ type Apply = Trees.Apply[Type]
+ type TypeApply = Trees.TypeApply[Type]
+ type Literal = Trees.Literal[Type]
+ type New = Trees.New[Type]
+ type Pair = Trees.Pair[Type]
+ type Typed = Trees.Typed[Type]
+ type NamedArg = Trees.NamedArg[Type]
+ type Assign = Trees.Assign[Type]
+ type Function = Trees.Function[Type]
+ type Block = Trees.Block[Type]
+ type If = Trees.If[Type]
+ type Match = Trees.Match[Type]
+ type CaseDef = Trees.CaseDef[Type]
+ type Return = Trees.Return[Type]
+ type Try = Trees.Try[Type]
+ type Throw = Trees.Throw[Type]
+ type ArrayValue = Trees.ArrayValue[Type]
+ type TypeTree = Trees.TypeTree[Type]
+ type SingletonTypeTree = Trees.SingletonTypeTree[Type]
+ type SelectFromTypeTree = Trees.SelectFromTypeTree[Type]
+ type AndTypeTree = Trees.AndTypeTree[Type]
+ type OrTypeTree = Trees.OrTypeTree[Type]
+ type RefineTypeTree = Trees.RefineTypeTree[Type]
+ type AppliedTypeTree = Trees.AppliedTypeTree[Type]
+ type TypeBoundsTree = Trees.TypeBoundsTree[Type]
+ type Bind = Trees.Bind[Type]
+ type Alternative = Trees.Alternative[Type]
+ type UnApply = Trees.UnApply[Type]
+ type ValDef = Trees.ValDef[Type]
+ type DefDef = Trees.DefDef[Type]
+ type TypeDef = Trees.TypeDef[Type]
+ type Template = Trees.Template[Type]
+ type ClassDef = Trees.ClassDef[Type]
+ type Import = Trees.Import[Type]
+ type PackageDef = Trees.PackageDef[Type]
+ type Annotated = Trees.Annotated[Type]
+ type EmptyTree = Trees.EmptyTree[Type]
+ type Shared = Trees.Shared[Type]
+
+ private implicit def pos(implicit ctx: Context): Position = ctx.position
+
+ def defPos(sym: Symbol)(implicit ctx: Context) = ctx.position union sym.coord.toPosition
+
+ def Modifiers(sym: Symbol)(implicit ctx: Context): Modifiers = Trees.Modifiers[Type](
+ sym.flags & ModifierFlags,
+ if (sym.privateWithin.exists) sym.privateWithin.asType.name else tpnme.EMPTY,
+ sym.annotations map (_.tree))
+
+ val Ident = Trees.Ident
+ def Ident(tp: NamedType)(implicit ctx: Context): Ident =
+ Trees.Ident(tp.name).withType(tp)
+
+ def Select(pre: Tree, tp: NamedType)(implicit ctx: Context): Select =
+ Trees.Select(pre, tp.name).withType(tp)
+
+ def This(cls: ClassSymbol)(implicit ctx: Context): This =
+ Trees.This(cls.name).withType(cls.thisType)
+
+ def Super(qual: Tree, mixin: Symbol = NoSymbol)(implicit ctx: Context): Super = {
+ val cls = qual.tpe.typeSymbol
+ val (owntype, mix) =
+ if (mixin.exists) (mixin.typeConstructor, mixin.asType.name)
+ else (ctx.glb(cls.info.parents), tpnme.EMPTY)
+ Trees.Super(qual, mix).withType(SuperType(qual.tpe, owntype))
+ }
+
+ def Apply(fn: Tree, args: List[Tree])(implicit ctx: Context): Apply = {
+ val fntpe @ MethodType(pnames, ptypes) = fn.tpe
+ assert(sameLength(ptypes, args))
+ Trees.Apply(fn, args).withType(fntpe.instantiate(args map (_.tpe)))
+ }
+
+ def TypeApply(fn: Tree, args: List[Tree])(implicit ctx: Context): TypeApply = {
+ val fntpe @ PolyType(pnames) = fn.tpe
+ assert(sameLength(pnames, args))
+ Trees.TypeApply(fn, args).withType(fntpe.instantiate(args map (_.tpe)))
+ }
+
+ def Literal(const: Constant)(implicit ctx: Context): Literal =
+ Trees.Literal(const).withType(const.tpe)
+
+ def New(tp: Type)(implicit ctx: Context): New =
+ Trees.New(TypeTree(tp))
+
+ def Pair(left: Tree, right: Tree)(implicit ctx: Context): Pair =
+ Trees.Pair(left, right).withType(defn.PairType.appliedTo(left.tpe, right.tpe))
+
+ def Typed(expr: Tree, tpt: Tree)(implicit ctx: Context): Typed =
+ Trees.Typed(expr, tpt).withType(tpt.tpe)
+
+ def NamedArg(name: Name, arg: Tree)(implicit ctx: Context) =
+ Trees.NamedArg(name, arg).withType(arg.tpe)
+
+ def Assign(lhs: Tree, rhs: Tree)(implicit ctx: Context): Assign =
+ Trees.Assign(lhs, rhs).withType(defn.UnitType)
+
+ def Function(vparams: List[ValDef], body: Tree)(implicit ctx: Context): Function =
+ Trees.Function(vparams, body)
+ .withType(defn.FunctionType(vparams map (_.tpt.tpe), body.tpe))
+
+ def Block(stats: List[Tree], expr: Tree)(implicit ctx: Context): Block =
+ Trees.Block(stats, expr).withType(expr.tpe) // !!! need to make sure that type does not refer to locals
+
+ def If(cond: Tree, thenp: Tree, elsep: Tree)(implicit ctx: Context): If =
+ Trees.If(cond, thenp, elsep).withType(thenp.tpe | elsep.tpe)
+
+ def Match(selector: Tree, cases: List[CaseDef])(implicit ctx: Context): Match =
+ Trees.Match(selector, cases).withType(ctx.lub(cases map (_.body.tpe)))
+
+ def CaseDef(pat: Tree, guard: Tree, body: Tree)(implicit ctx: Context): CaseDef =
+ Trees.CaseDef(pat, guard, body).withType(body.tpe)
+
+ def Return(expr: Tree, from: Ident)(implicit ctx: Context): Return =
+ Trees.Return(expr, from).withType(defn.NothingType)
+
+ def Throw(expr: Tree)(implicit ctx: Context): Throw =
+ Trees.Throw(expr).withType(defn.NothingType)
+
+ def ArrayValue(elemtpt: Tree, elems: List[Tree])(implicit ctx: Context): ArrayValue =
+ Trees.ArrayValue(elemtpt, elems).withType(defn.ArrayType.appliedTo(elemtpt.tpe))
+
+ def TypeTree(tp: Type, original: Tree = EmptyTree)(implicit ctx: Context): TypeTree =
+ Trees.TypeTree(original).withType(tp)
+
+ def SingletonTypeTree(ref: Tree)(implicit ctx: Context): SingletonTypeTree =
+ Trees.SingletonTypeTree(ref).withType(ref.tpe)
+
+ def SelectFromTypeTree(qualifier: Tree, name: TypeName)(implicit ctx: Context): SelectFromTypeTree =
+ Trees.SelectFromTypeTree(qualifier, name).withType(TypeRef(qualifier.tpe, name))
+
+ def AndTypeTree(left: Tree, right: Tree)(implicit ctx: Context): AndTypeTree =
+ Trees.AndTypeTree(left, right).withType(left.tpe & right.tpe)
+
+ def OrTypeTree(left: Tree, right: Tree)(implicit ctx: Context): OrTypeTree =
+ Trees.OrTypeTree(left, right).withType(left.tpe | right.tpe)
+
+ def RefineTypeTree(tpt: Tree, refinements: List[DefTree])(implicit ctx: Context): RefineTypeTree = {
+ def refineType(tp: Type, refinement: Symbol): Type =
+ RefinedType(tp, refinement.name, refinement.info)
+ Trees.RefineTypeTree(tpt, refinements)
+ .withType((tpt.tpe /: (refinements map (_.symbol)))(refineType))
+ }
+
+ def refineType(tp: Type, refinement: Symbol)(implicit ctx: Context): Type =
+ RefinedType(tp, refinement.name, refinement.info)
+
+ def AppliedTypeTree(tpt: Tree, args: List[Tree])(implicit ctx: Context): AppliedTypeTree =
+ Trees.AppliedTypeTree(tpt, args).withType(tpt.tpe.appliedTo(args map (_.tpe)))
+
+ def TypeBoundsTree(lo: Tree, hi: Tree)(implicit ctx: Context): TypeBoundsTree =
+ Trees.TypeBoundsTree(lo, hi).withType(TypeBounds(lo.tpe, hi.tpe))
+
+ def Bind(sym: Symbol, body: Tree)(implicit ctx: Context): Bind =
+ Trees.Bind(sym.name, body)(defPos(sym)).withType(sym.info)
+
+ def Alternative(trees: List[Tree])(implicit ctx: Context): Alternative =
+ Trees.Alternative(trees).withType(ctx.lub(trees map (_.tpe)))
+
+ def UnApply(fun: Tree, args: List[Tree])(implicit ctx: Context): UnApply =
+ Trees.UnApply(fun, args).withType(fun.tpe match {
+ case MethodType(_, paramTypes) => paramTypes.head
+ })
+
+ def refType(sym: Symbol)(implicit ctx: Context) = NamedType(sym.owner.thisType, sym)
+
+ def ValDef(sym: TermSymbol, rhs: Tree = EmptyTree)(implicit ctx: Context): ValDef =
+ Trees.ValDef(Modifiers(sym), sym.name, TypeTree(sym.info), rhs)(defPos(sym))
+ .withType(refType(sym))
+
+ def DefDef(sym: TermSymbol, rhs: Tree = EmptyTree)(implicit ctx: Context): DefDef = {
+
+ val (tparams, mtp) = sym.info match {
+ case tp: PolyType =>
+ def paramBounds(trefs: List[TypeRef]): List[Type] =
+ tp.paramBounds map new InstPolyMap(tp, trefs)
+ val tparams = ctx.newTypeParams(sym, tp.paramNames, EmptyFlags, paramBounds)
+ (tparams, tp.instantiate(tparams map (_.typeConstructor)))
+ case tp => (Nil, tp)
+ }
+
+ def valueParamss(tp: Type): (List[List[TermSymbol]], Type) = tp match {
+ case tp @ MethodType(paramNames, paramTypes) =>
+ def valueParam(name: TermName, info: Type): TermSymbol =
+ ctx.newSymbol(sym, name, TermParam, info)
+ val params = (paramNames, paramTypes).zipped.map(valueParam)
+ val (paramss, rtp) = valueParamss(tp.instantiate(params map (_.typeConstructor)))
+ (params :: paramss, rtp)
+ case tp => (Nil, tp)
+ }
+ val (vparamss, rtp) = valueParamss(mtp)
+
+ Trees.DefDef(
+ Modifiers(sym), sym.name, tparams map TypeDef,
+ vparamss map (_ map (ValDef(_))), TypeTree(rtp), rhs)(defPos(sym))
+ .withType(refType(sym))
+ }
+
+ def TypeDef(sym: TypeSymbol)(implicit ctx: Context): TypeDef =
+ Trees.TypeDef(Modifiers(sym), sym.name, TypeTree(sym.info))(defPos(sym))
+ .withType(refType(sym))
+
+ def ClassDef(cls: ClassSymbol, typeParams: List[TypeSymbol], body: List[Tree])(implicit ctx: Context): ClassDef = {
+ val parents = cls.info.parents map (TypeTree(_))
+ val selfType =
+ if (cls.selfType eq cls.typeConstructor) EmptyValDef
+ else ValDef(ctx.newSelfSym(cls))
+ def isOwnTypeParamAccessor(stat: Tree) =
+ stat.symbol.owner == cls && (stat.symbol is TypeParam)
+ val (tparamAccessors, rest) = body partition isOwnTypeParamAccessor
+ val tparams =
+ (typeParams map TypeDef) ++
+ (tparamAccessors collect {
+ case td: TypeDef if !(typeParams contains td.symbol) => td
+ })
+ val findLocalDummy = new FindLocalDummyAccumulator(cls)
+ val localDummy = ((NoSymbol: Symbol) /: body)(findLocalDummy)
+ .orElse(ctx.newLocalDummy(cls))
+ val impl = Trees.Template(parents, selfType, rest)
+ .withType(refType(localDummy))
+ Trees.ClassDef(Modifiers(cls), cls.name, tparams, impl)(defPos(cls))
+ .withType(refType(cls))
+ }
+
+ def Import(expr: Tree, selectors: List[Trees.UntypedTree])(implicit ctx: Context): Import =
+ Trees.Import(expr, selectors).withType(refType(ctx.newImportSymbol(expr)))
+
+ def PackageDef(pid: RefTree, stats: List[Tree])(implicit ctx: Context): PackageDef =
+ Trees.PackageDef(pid, stats).withType(refType(pid.symbol))
+
+ def Annotated(annot: Tree, arg: Tree)(implicit ctx: Context): Annotated =
+ Trees.Annotated(annot, arg).withType(AnnotatedType(List(Annotation(annot)), arg.tpe))
+
+ val EmptyTree: Tree = Trees.EmptyTree[Type]
+
+ val EmptyValDef: ValDef = Trees.EmptyValDef[Type]
+
+ def Shared(tree: Tree): Shared =
+ Trees.Shared(tree).withType(tree.tpe)
+
+ // -----------------------------------------------------------------------------
+
+ def New(tp: Type, args: List[Tree])(implicit ctx: Context): Apply =
+ Apply(
+ Select(
+ New(tp),
+ TermRef(tp.normalizedPrefix, tp.typeSymbol.primaryConstructor.asTerm)),
+ args)
+
+ def ModuleDef(sym: TermSymbol, body: List[Tree])(implicit ctx: Context): ValDef = {
+ val modcls = sym.moduleClass.asClass
+ val clsdef = ClassDef(modcls, Nil, body)
+ val rhs = Block(List(clsdef), New(modcls.typeConstructor))
+ ValDef(sym, rhs)
+ }
+
+ private class FindLocalDummyAccumulator(cls: ClassSymbol)(implicit ctx: Context) extends TreeAccumulator[Symbol] {
+ def apply(sym: Symbol, tree: Tree) =
+ if (sym.exists) sym
+ else if (tree.isDef) {
+ val owner = tree.symbol.owner
+ if (owner.isLocalDummy && owner.owner == cls) owner
+ else if (owner == cls) foldOver(sym, tree)
+ else sym
+ } else foldOver(sym, tree)
+ }
+}
+
diff --git a/src/dotty/tools/dotc/core/pickling/ClassfileParser.scala b/src/dotty/tools/dotc/core/pickling/ClassfileParser.scala
index 9955d8b56..d131fe8f8 100644
--- a/src/dotty/tools/dotc/core/pickling/ClassfileParser.scala
+++ b/src/dotty/tools/dotc/core/pickling/ClassfileParser.scala
@@ -4,7 +4,7 @@ package core
package pickling
import Contexts._, Symbols._, Types._, Names._, StdNames._, NameOps._, Scopes._, Decorators._
-import SymDenotations._, UnPickler._, Constants._, Trees._, Annotations._, Positions._
+import SymDenotations._, UnPickler._, Constants._, Annotations._, Positions._
import TypedTrees._
import java.io.{ File, IOException }
import java.lang.Integer.toHexString
@@ -125,11 +125,7 @@ class ClassfileParser(
instanceScope.lookup(nme.CONSTRUCTOR) == NoSymbol && !(sflags is Flags.Interface)
if (needsConstructor)
- instanceScope enter
- cctx.newSymbol(
- classRoot.symbol,
- nme.CONSTRUCTOR, Flags.EmptyFlags,
- MethodType(Nil, Nil)(_ => classRoot.typeConstructor))
+ instanceScope enter cctx.newDefaultConstructor(classRoot.symbol.asClass)
classInfo = parseAttributes(classRoot.symbol, classInfo)
assignClassFields(classRoot, classInfo, classRoot.typeConstructor)
@@ -158,41 +154,39 @@ class ClassfileParser(
cctx.newLazySymbol(getOwner(jflags), name, sflags, memberCompleter, start).entered
}
- object memberCompleter extends SymCompleter {
- def complete(denot: LazySymDenotation) = {
- val oldbp = in.bp
- try {
- in.bp = denot.symbol.coord.toIndex
- val sym = denot.symbol
- val jflags = in.nextChar
- val isEnum = (jflags & JAVA_ACC_ENUM) != 0
- val name = pool.getName(in.nextChar)
- val info = pool.getType(in.nextChar)
-
- denot.info = if (isEnum) ConstantType(Constant(sym)) else info
- if (name == nme.CONSTRUCTOR)
- // if this is a non-static inner class, remove the explicit outer parameter
- innerClasses.get(currentClassName) match {
- case Some(entry) if !isStatic(entry.jflags) =>
- val mt @ MethodType(paramnames, paramtypes) = info
- denot.info = mt.derivedMethodType(paramnames.tail, paramtypes.tail, mt.resultType)
-
- }
- setPrivateWithin(denot, jflags)
- denot.info = parseAttributes(sym, info)
+ val memberCompleter: SymCompleter = { denot =>
+ val oldbp = in.bp
+ try {
+ in.bp = denot.symbol.coord.toIndex
+ val sym = denot.symbol
+ val jflags = in.nextChar
+ val isEnum = (jflags & JAVA_ACC_ENUM) != 0
+ val name = pool.getName(in.nextChar)
+ val info = pool.getType(in.nextChar)
- if ((denot is Flags.Method) && (jflags & JAVA_ACC_VARARGS) != 0)
- denot.info = arrayToRepeated(denot.info)
+ denot.info = if (isEnum) ConstantType(Constant(sym)) else info
+ if (name == nme.CONSTRUCTOR)
+ // if this is a non-static inner class, remove the explicit outer parameter
+ innerClasses.get(currentClassName) match {
+ case Some(entry) if !isStatic(entry.jflags) =>
+ val mt @ MethodType(paramnames, paramtypes) = info
+ denot.info = mt.derivedMethodType(paramnames.tail, paramtypes.tail, mt.resultType)
- // seal java enums
- if (isEnum) {
- val enumClass = sym.owner.linkedClass
- if (!(enumClass is Flags.Sealed)) enumClass.setFlag(Flags.AbstractSealed)
- enumClass.addAnnotation(Annotation.makeChild(sym))
}
- } finally {
- in.bp = oldbp
+ setPrivateWithin(denot, jflags)
+ denot.info = parseAttributes(sym, info)
+
+ if ((denot is Flags.Method) && (jflags & JAVA_ACC_VARARGS) != 0)
+ denot.info = arrayToRepeated(denot.info)
+
+ // seal java enums
+ if (isEnum) {
+ val enumClass = sym.owner.linkedClass
+ if (!(enumClass is Flags.Sealed)) enumClass.setFlag(Flags.AbstractSealed)
+ enumClass.addAnnotation(Annotation.makeChild(sym))
}
+ } finally {
+ in.bp = oldbp
}
}
@@ -315,15 +309,13 @@ class ClassfileParser(
var tparams = classTParams
- class TypeParamCompleter(start: Int) extends SymCompleter {
- override def complete(denot: LazySymDenotation): Unit = {
- val savedIndex = index
- try {
- index = start
- denot.info = sig2typeBounds(tparams, skiptvs = false)
- } finally {
- index = savedIndex
- }
+ def typeParamCompleter(start: Int): SymCompleter = { denot =>
+ val savedIndex = index
+ try {
+ index = start
+ denot.info = sig2typeBounds(tparams, skiptvs = false)
+ } finally {
+ index = savedIndex
}
}
@@ -335,7 +327,7 @@ class ClassfileParser(
while (sig(index) != '>') {
val tpname = subName(':'.==).toTypeName
val s = cctx.newLazySymbol(
- owner, tpname, Flags.TypeParam, new TypeParamCompleter(index), indexCoord(index))
+ owner, tpname, Flags.TypeParam, typeParamCompleter(index), indexCoord(index))
tparams = tparams + (tpname -> s)
sig2typeBounds(tparams, skiptvs = true)
newTParams += s
@@ -356,7 +348,7 @@ class ClassfileParser(
if (ownTypeParams.isEmpty) tpe else TempPolyType(ownTypeParams, tpe)
} // sigToType
- def parseAnnotArg(skip: Boolean = false): Option[TypedTree] = {
+ def parseAnnotArg(skip: Boolean = false): Option[Tree] = {
val tag = in.nextByte.toChar
val index = in.nextChar
tag match {
@@ -374,7 +366,7 @@ class ClassfileParser(
assert(s != NoSymbol, t)
if (skip) None else Some(makeLiteralAnnotArg(Constant(s)))
case ARRAY_TAG =>
- val arr = new ArrayBuffer[TypedTree]()
+ val arr = new ArrayBuffer[Tree]()
var hasError = false
for (i <- 0 until index)
parseAnnotArg(skip) match {
@@ -394,12 +386,12 @@ class ClassfileParser(
def parseAnnotation(attrNameIndex: Char, skip: Boolean = false): Option[Annotation] = try {
val attrType = pool.getType(attrNameIndex)
val nargs = in.nextChar
- val argbuf = new ListBuffer[TypedTree]
+ val argbuf = new ListBuffer[Tree]
var hasError = false
for (i <- 0 until nargs) {
val name = pool.getName(in.nextChar)
parseAnnotArg(skip) match {
- case Some(arg) => argbuf += tpd.NamedArg(name, arg)
+ case Some(arg) => argbuf += NamedArg(name, arg)
case None => hasError = !skip
}
}
@@ -444,8 +436,8 @@ class ClassfileParser(
case tpnme.BridgeATTR =>
sym.setFlag(Flags.Bridge)
case tpnme.DeprecatedATTR =>
- val msg = tpd.Literal(Constant("see corresponding Javadoc for more information."))
- val since = tpd.Literal(Constant(""))
+ val msg = Literal(Constant("see corresponding Javadoc for more information."))
+ val since = Literal(Constant(""))
sym.addAnnotation(Annotation(defn.DeprecatedAnnot, msg, since))
case tpnme.ConstantValueATTR =>
val c = pool.getConstant(in.nextChar)
diff --git a/src/dotty/tools/dotc/core/pickling/UnPickler.scala b/src/dotty/tools/dotc/core/pickling/UnPickler.scala
index e3d08b304..7a06b098e 100644
--- a/src/dotty/tools/dotc/core/pickling/UnPickler.scala
+++ b/src/dotty/tools/dotc/core/pickling/UnPickler.scala
@@ -9,7 +9,7 @@ import java.lang.Double.longBitsToDouble
import Contexts._, Symbols._, Types._, Scopes._, SymDenotations._, Names._
import StdNames._, Denotations._, NameOps._, Flags._, Constants._, Annotations._
-import Trees._, Positions._, TypedTrees._
+import Positions._, TypedTrees._
import io.AbstractFile
import scala.reflect.internal.pickling.PickleFormat._
import scala.collection.{ mutable, immutable }
@@ -422,13 +422,8 @@ class UnPickler(bytes: Array[Byte], classRoot: LazyClassDenotation, moduleRoot:
atReadPos(denot.symbol.coord.toIndex, parseToCompletion)
}
- private object symUnpickler extends SymCompleter {
- override def complete(denot: LazySymDenotation): Unit = completeLocal(denot)
- }
-
- private object classUnpickler extends ClassCompleter {
- override def complete(denot: LazyClassDenotation): Unit = completeLocal(denot)
- }
+ val symUnpickler: SymCompleter = completeLocal
+ val classUnpickler: ClassCompleter = completeLocal
/** Convert
* tp { type name = sym } forSome { sym >: L <: H }
@@ -625,36 +620,36 @@ class UnPickler(bytes: Array[Byte], classRoot: LazyClassDenotation, moduleRoot:
protected def readAnnotationRef(): Annotation = at(readNat(), readAnnotation)
// protected def readModifiersRef(): Modifiers = at(readNat(), readModifiers)
- protected def readTreeRef(): TypedTree = at(readNat(), readTree)
+ protected def readTreeRef(): Tree = at(readNat(), readTree)
- protected def readTree(): TypedTree = ???
+ protected def readTree(): Tree = ???
/** Read an annotation argument, which is pickled either
* as a Constant or a Tree.
*/
- protected def readAnnotArg(i: Int): TypedTree = bytes(index(i)) match {
+ protected def readAnnotArg(i: Int): Tree = bytes(index(i)) match {
case TREE => at(i, readTree)
- case _ => tpd.Literal(at(i, readConstant))
+ case _ => Literal(at(i, readConstant))
}
/** Read a ClassfileAnnotArg (argument to a classfile annotation)
*/
- private def readArrayAnnotArg(): TypedTree = {
+ private def readArrayAnnotArg(): Tree = {
readByte() // skip the `annotargarray` tag
val end = readNat() + readIndex
// array elements are trees representing instances of scala.annotation.Annotation
- tpd.ArrayValue(
- tpd.TypeTree(defn.AnnotationClass.typeConstructor),
+ ArrayValue(
+ TypeTree(defn.AnnotationClass.typeConstructor),
until(end, () => readClassfileAnnotArg(readNat())))
}
- private def readAnnotInfoArg(): TypedTree = {
+ private def readAnnotInfoArg(): Tree = {
readByte() // skip the `annotinfo` tag
val end = readNat() + readIndex
readAnnotationContents(end)
}
- protected def readClassfileAnnotArg(i: Int): TypedTree = bytes(index(i)) match {
+ protected def readClassfileAnnotArg(i: Int): Tree = bytes(index(i)) match {
case ANNOTINFO => at(i, readAnnotInfoArg)
case ANNOTARGARRAY => at(i, readArrayAnnotArg)
case _ => readAnnotArg(i)
@@ -663,20 +658,20 @@ class UnPickler(bytes: Array[Byte], classRoot: LazyClassDenotation, moduleRoot:
/** Read an annotation's contents. Not to be called directly, use
* readAnnotation, readSymbolAnnotation, or readAnnotInfoArg
*/
- protected def readAnnotationContents(end: Int): TypedTree = {
+ protected def readAnnotationContents(end: Int): Tree = {
val atp = readTypeRef()
- val args = new ListBuffer[TypedTree]
+ val args = new ListBuffer[Tree]
while (readIndex != end) {
val argref = readNat()
args += {
if (isNameEntry(argref)) {
val name = at(argref, readName)
val arg = readClassfileAnnotArg(readNat())
- tpd.NamedArg(name, arg)
+ NamedArg(name, arg)
} else readAnnotArg(argref)
}
}
- tpd.New(atp, args.toList)
+ New(atp, args.toList)
}
/** Read an annotation and as a side effect store it into