Permalink
Browse files

A little clarity for AddInterfaces.

And a couple conveniences elsewhere.
  • Loading branch information...
paulp committed May 2, 2012
1 parent edc4a72 commit 15e05a400be378b012903411179f2a4114f890ef
@@ -2054,7 +2054,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
def sealedDescendants: Set[Symbol] = children.flatMap(_.sealedDescendants) + this
@inline final def orElse(alt: => Symbol): Symbol = if (this ne NoSymbol) this else alt
@inline final def andAlso(f: Symbol => Unit): Symbol = if (this eq NoSymbol) NoSymbol else { f(this) ; this }
@inline final def andAlso(f: Symbol => Unit): Symbol = { if (this ne NoSymbol) f(this) ; this }
// ------ toString -------------------------------------------------------------------
@@ -204,25 +204,22 @@ abstract class AddInterfaces extends InfoTransform { self: Erasure =>
def transformMixinInfo(tp: Type): Type = tp match {
case ClassInfoType(parents, decls, clazz) =>
if (clazz.needsImplClass) {
clazz setFlag lateINTERFACE
implClass(clazz) // generate an impl class
}
if (clazz.needsImplClass)
implClass(clazz setFlag lateINTERFACE) // generate an impl class
val parents1 = parents match {
case Nil => Nil
case hd :: tl =>
assert(!hd.typeSymbol.isTrait, clazz)
if (clazz.isTrait) erasedTypeRef(ObjectClass) :: tl
else parents
}
val decls1 = scopeTransform(clazz) { decls filter (sym =>
if (clazz.isInterface) isInterfaceMember(sym)
else (!sym.isType || sym.isClass))
}
//if (!clazz.isPackageClass) System.out.println("Decls of "+clazz+" after explicitOuter = " + decls1);//DEBUG
//if ((parents1 eq parents) && (decls1 eq decls)) tp
//else
val decls1 = scopeTransform(clazz)(
decls filter (sym =>
if (clazz.isInterface) isInterfaceMember(sym)
else sym.isClass || sym.isTerm
)
)
ClassInfoType(parents1, decls1, clazz)
case _ =>
tp
@@ -242,27 +239,29 @@ abstract class AddInterfaces extends InfoTransform { self: Erasure =>
}
}
private def ifaceMemberDef(tree: Tree): Tree =
if (!tree.isDef || !isInterfaceMember(tree.symbol)) EmptyTree
else if (needsImplMethod(tree.symbol)) DefDef(tree.symbol, EmptyTree)
else tree
private def createMemberDef(tree: Tree, isForInterface: Boolean)(create: Tree => Tree) = {
val isInterfaceTree = tree.isDef && isInterfaceMember(tree.symbol)
if (isInterfaceTree && needsImplMethod(tree.symbol))
create(tree)
else if (isInterfaceTree == isForInterface)
tree
else
EmptyTree
}
private def implMemberDef(tree: Tree): Tree = createMemberDef(tree, false)(implMethodDef)
private def ifaceMemberDef(tree: Tree): Tree = createMemberDef(tree, true)(t => DefDef(t.symbol, EmptyTree))
private def ifaceTemplate(templ: Template): Template =
treeCopy.Template(templ, templ.parents, emptyValDef, templ.body map ifaceMemberDef)
private def implMethodDef(tree: Tree, ifaceMethod: Symbol): Tree =
implMethodMap.get(ifaceMethod) match {
case Some(implMethod) =>
tree.symbol = implMethod
new ChangeOwnerAndReturnTraverser(ifaceMethod, implMethod)(tree)
case None =>
abort("implMethod missing for " + ifaceMethod)
}
private def implMemberDef(tree: Tree): Tree =
if (!tree.isDef || !isInterfaceMember(tree.symbol)) tree
else if (needsImplMethod(tree.symbol)) implMethodDef(tree, tree.symbol)
else EmptyTree
/** Transforms the member tree containing the implementation
* into a member of the impl class.
*/
private def implMethodDef(tree: Tree): Tree = (
implMethodMap get tree.symbol
map (impl => new ChangeOwnerAndReturnTraverser(tree.symbol, impl)(tree setSymbol impl))
getOrElse abort("implMethod missing for " + tree.symbol)
)
/** Add mixin constructor definition
* def $init$(): Unit = ()
@@ -334,14 +333,12 @@ abstract class AddInterfaces extends InfoTransform { self: Erasure =>
case Template(parents, self, body) =>
val parents1 = sym.owner.info.parents map (t => TypeTree(t) setPos tree.pos)
treeCopy.Template(tree, parents1, emptyValDef, body)
case This(_) =>
if (sym.needsImplClass) {
val impl = implClass(sym)
var owner = currentOwner
while (owner != sym && owner != impl) owner = owner.owner;
if (owner == impl) This(impl) setPos tree.pos
else tree
} else tree
case This(_) if sym.needsImplClass =>
val impl = implClass(sym)
var owner = currentOwner
while (owner != sym && owner != impl) owner = owner.owner;
if (owner == impl) This(impl) setPos tree.pos
else tree
/* !!!
case Super(qual, mix) =>
val mix1 = mix
@@ -124,6 +124,9 @@ trait Trees { self: Universe =>
def tpe = rawtpe
def tpe_=(t: Type) = rawtpe = t
def resetType(): this.type = { tpe = null ; this }
def resetSymbol(): this.type = { if (hasSymbol) symbol = NoSymbol ; this }
/** Set tpe to give `tp` and return this.
*/
def setType(tp: Type): this.type = { rawtpe = tp; this }
@@ -134,7 +137,7 @@ trait Trees { self: Universe =>
* @PP: Attempting to elaborate on the above, I find: If defineType
* is called on a TypeTree whose type field is null or NoType,
* this is recorded as "wasEmpty = true". That value is used in
* ResetAttrsTraverser, which nulls out the type field of TypeTrees
* ResetAttrs, which nulls out the type field of TypeTrees
* for which wasEmpty is true, leaving the others alone.
*
* resetAllAttrs is used in situations where some speculative
@@ -169,9 +172,14 @@ trait Trees { self: Universe =>
def hasSymbol = false
def isDef = false
def isEmpty = false
def orElse(alt: => Tree) = if (!isEmpty) this else alt
@inline final def orElse(alt: => Tree) = if (!isEmpty) this else alt
@inline final def andAlso(f: Tree => Unit): Tree = { if (!this.isEmpty) f(this) ; this }
def hasAssignedType = (tpe ne null) && (tpe ne NoType)
def hasAssignedSymbol = (symbol ne null) && (symbol ne NoSymbol)
def hasSymbolWhich(f: Symbol => Boolean) = hasSymbol && f(symbol)
@inline final def hasSymbolWhich(f: Symbol => Boolean) = hasAssignedSymbol && f(symbol)
@inline final def hasTypeWhich(f: Type => Boolean) = hasAssignedType && f(tpe)
/** The canonical way to test if a Tree represents a term.
*/
@@ -325,6 +333,7 @@ trait Trees { self: Universe =>
override def tpe_=(t: Type) =
if (t != NoType) throw new UnsupportedOperationException("tpe_=("+t+") inapplicable for <empty>")
override def isEmpty = true
override def resetType(): this.type = this
}
/** Common base class for all member definitions: types, classes,
@@ -622,6 +631,9 @@ trait Trees { self: Universe =>
*/
case class TypeApply(fun: Tree, args: List[Tree])
extends GenericApply {
// Testing the above theory re: args.nonEmpty.
require(args.nonEmpty, this)
override def symbol: Symbol = fun.symbol
override def symbol_=(sym: Symbol) { fun.symbol = sym }
}
@@ -773,8 +785,8 @@ trait Trees { self: Universe =>
case t => t
}
orig = followOriginal(tree); setPos(tree.pos);
this
orig = followOriginal(tree)
this setPos tree.pos
}
override def defineType(tp: Type): this.type = {

0 comments on commit 15e05a4

Please sign in to comment.