diff options
author | Paul Phillips <paulp@improving.org> | 2012-05-01 18:51:26 -0700 |
---|---|---|
committer | Paul Phillips <paulp@improving.org> | 2012-05-01 19:52:09 -0700 |
commit | 15e05a400be378b012903411179f2a4114f890ef (patch) | |
tree | c07ee69df8fe5c4b64b73482d7a45ce94b758abb | |
parent | edc4a7292f5a45f4ad03124de40303f0f443ba9b (diff) | |
download | scala-15e05a400be378b012903411179f2a4114f890ef.tar.gz scala-15e05a400be378b012903411179f2a4114f890ef.tar.bz2 scala-15e05a400be378b012903411179f2a4114f890ef.zip |
A little clarity for AddInterfaces.
And a couple conveniences elsewhere.
-rw-r--r-- | src/compiler/scala/reflect/internal/Symbols.scala | 2 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/transform/AddInterfaces.scala | 71 | ||||
-rw-r--r-- | src/library/scala/reflect/api/Trees.scala | 22 |
3 files changed, 52 insertions, 43 deletions
diff --git a/src/compiler/scala/reflect/internal/Symbols.scala b/src/compiler/scala/reflect/internal/Symbols.scala index c2ef633d58..78cec02c0a 100644 --- a/src/compiler/scala/reflect/internal/Symbols.scala +++ b/src/compiler/scala/reflect/internal/Symbols.scala @@ -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 ------------------------------------------------------------------- diff --git a/src/compiler/scala/tools/nsc/transform/AddInterfaces.scala b/src/compiler/scala/tools/nsc/transform/AddInterfaces.scala index 3581f1b923..cb7d64b9fc 100644 --- a/src/compiler/scala/tools/nsc/transform/AddInterfaces.scala +++ b/src/compiler/scala/tools/nsc/transform/AddInterfaces.scala @@ -204,10 +204,9 @@ 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 => @@ -215,14 +214,12 @@ abstract class AddInterfaces extends InfoTransform { self: Erasure => 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 diff --git a/src/library/scala/reflect/api/Trees.scala b/src/library/scala/reflect/api/Trees.scala index 9f8906a8cd..f1e9cc13ca 100644 --- a/src/library/scala/reflect/api/Trees.scala +++ b/src/library/scala/reflect/api/Trees.scala @@ -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 = { |