diff options
author | Adriaan Moors <adriaan.moors@typesafe.com> | 2015-10-01 15:12:32 -0700 |
---|---|---|
committer | Adriaan Moors <adriaan.moors@typesafe.com> | 2015-11-11 15:52:33 -0800 |
commit | 279e785d0b204b816359d5eeb3e3cbbc6215e0ee (patch) | |
tree | 2d45a390afa1fdd298defd52646a5eb2ee162d40 /src/compiler | |
parent | 5d9ed5c752b12f5cd138e707dfd53b00066efe66 (diff) | |
download | scala-279e785d0b204b816359d5eeb3e3cbbc6215e0ee.tar.gz scala-279e785d0b204b816359d5eeb3e3cbbc6215e0ee.tar.bz2 scala-279e785d0b204b816359d5eeb3e3cbbc6215e0ee.zip |
Cleanups, debuglogs, small refactorings
Diffstat (limited to 'src/compiler')
4 files changed, 88 insertions, 77 deletions
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/BCodeHelpers.scala b/src/compiler/scala/tools/nsc/backend/jvm/BCodeHelpers.scala index e1cee8861a..728a0b574d 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/BCodeHelpers.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/BCodeHelpers.scala @@ -1052,7 +1052,7 @@ abstract class BCodeHelpers extends BCodeIdiomatic with BytecodeWriters { for (m <- moduleClass.info.membersBasedOnFlags(BCodeHelpers.ExcludedForwarderFlags, symtab.Flags.METHOD)) { if (m.isType || m.isDeferred || (m.owner eq definitions.ObjectClass) || m.isConstructor) - debuglog(s"No forwarder for '$m' from $jclassName to '$moduleClass'") + debuglog(s"No forwarder for '$m' from $jclassName to '$moduleClass': ${m.isType} || ${m.isDeferred} || ${m.owner eq definitions.ObjectClass} || ${m.isConstructor}") else if (conflictingNames(m.name)) log(s"No forwarder for $m due to conflict with ${linkedClass.info.member(m.name)}") else if (m.hasAccessBoundary) diff --git a/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala b/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala index f12f6c4e18..854acd63c0 100644 --- a/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala +++ b/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala @@ -159,19 +159,24 @@ abstract class ExplicitOuter extends InfoTransform * elides outer pointers. */ def transformInfo(sym: Symbol, tp: Type): Type = tp match { - case MethodType(params, restpe1) => - val restpe = transformInfo(sym, restpe1) - if (sym.owner.isTrait && ((sym hasFlag (ACCESSOR | SUPERACCESSOR)) || sym.isModule)) { // 5 - sym.makeNotPrivate(sym.owner) + case MethodType(params, resTp) => + val resTpTransformed = transformInfo(sym, resTp) + + // juggle flags (and mangle names) after transforming info + if (sym.owner.isTrait) { + // TODO: I don't believe any private accessors remain after the fields phase + if ((sym hasFlag (ACCESSOR | SUPERACCESSOR)) || sym.isModule) sym.makeNotPrivate(sym.owner) // 5 + if (sym.isProtected) sym setFlag notPROTECTED // 6 } - if (sym.owner.isTrait && sym.isProtected) sym setFlag notPROTECTED // 6 - if (sym.isClassConstructor && isInner(sym.owner)) { // 1 - val p = sym.newValueParameter(innerClassConstructorParamName, sym.pos) - .setInfo(sym.owner.outerClass.thisType) - MethodType(p :: params, restpe) - } else if (restpe ne restpe1) - MethodType(params, restpe) + + val paramsWithOuter = + if (sym.isClassConstructor && isInner(sym.owner)) // 1 + sym.newValueParameter(innerClassConstructorParamName, sym.pos).setInfo(sym.owner.outerClass.thisType) :: params + else params + + if ((resTpTransformed ne resTp) || (paramsWithOuter ne params)) MethodType(paramsWithOuter, resTpTransformed) else tp + case ClassInfoType(parents, decls, clazz) => var decls1 = decls if (isInner(clazz) && !clazz.isInterface) { diff --git a/src/compiler/scala/tools/nsc/transform/LambdaLift.scala b/src/compiler/scala/tools/nsc/transform/LambdaLift.scala index d1be1558b9..01714e22fd 100644 --- a/src/compiler/scala/tools/nsc/transform/LambdaLift.scala +++ b/src/compiler/scala/tools/nsc/transform/LambdaLift.scala @@ -148,7 +148,7 @@ abstract class LambdaLift extends InfoTransform { * } */ private def markFree(sym: Symbol, enclosure: Symbol): Boolean = { - debuglog("mark free: " + sym.fullLocationString + " marked free in " + enclosure) +// println(s"mark free: ${sym.fullLocationString} marked free in $enclosure") (enclosure == sym.owner.logicallyEnclosingMember) || { debuglog("%s != %s".format(enclosure, sym.owner.logicallyEnclosingMember)) if (enclosure.isPackageClass || !markFree(sym, enclosure.skipConstructor.owner.logicallyEnclosingMember)) false @@ -158,7 +158,7 @@ abstract class LambdaLift extends InfoTransform { ss += sym renamable += sym changedFreeVars = true - debuglog("" + sym + " is free in " + enclosure) + debuglog(s"$sym is free in $enclosure") if (sym.isVariable) sym setFlag CAPTURED } !enclosure.isClass @@ -167,7 +167,7 @@ abstract class LambdaLift extends InfoTransform { } private def markCalled(sym: Symbol, owner: Symbol) { - debuglog("mark called: " + sym + " of " + sym.owner + " is called by " + owner) +// println(s"mark called: $sym of ${sym.owner} is called by $owner") symSet(called, owner) += sym if (sym.enclClass != owner.enclClass) calledFromInner += sym } @@ -175,7 +175,7 @@ abstract class LambdaLift extends InfoTransform { /** The traverse function */ private val freeVarTraverser = new Traverser { override def traverse(tree: Tree) { - try { //debug +// try { //debug val sym = tree.symbol tree match { case ClassDef(_, _, _, _) => @@ -222,11 +222,11 @@ abstract class LambdaLift extends InfoTransform { case _ => } super.traverse(tree) - } catch {//debug - case ex: Throwable => - Console.println(s"$ex while traversing $tree") - throw ex - } +// } catch {//debug +// case ex: Throwable => +// Console.println(s"$ex while traversing $tree") +// throw ex +// } } } @@ -240,7 +240,7 @@ abstract class LambdaLift extends InfoTransform { do { changedFreeVars = false - for (caller <- called.keys ; callee <- called(caller) ; fvs <- free get callee ; fv <- fvs) + for ((caller, callees) <- called ; callee <- callees ; fvs <- free get callee ; fv <- fvs) markFree(fv, caller) } while (changedFreeVars) @@ -308,11 +308,14 @@ abstract class LambdaLift extends InfoTransform { afterOwnPhase { for ((owner, freeValues) <- free.toList) { - val newFlags = SYNTHETIC | ( if (owner.isClass) PARAMACCESSOR | PrivateLocal else PARAM ) - debuglog("free var proxy: %s, %s".format(owner.fullLocationString, freeValues.toList.mkString(", "))) + val newFlags = SYNTHETIC | ( + if (owner.isClass) PARAMACCESSOR | PrivateLocal + else PARAM) + proxies(owner) = for (fv <- freeValues.toList) yield { val proxyName = proxyNames.getOrElse(fv, fv.name) + debuglog(s"new proxy ${proxyName} in ${owner.fullLocationString}") val proxy = owner.newValue(proxyName.toTermName, owner.pos, newFlags.toLong) setInfo fv.info if (owner.isClass) owner.info.decls enter proxy proxy @@ -342,31 +345,31 @@ abstract class LambdaLift extends InfoTransform { private def memberRef(sym: Symbol): Tree = { val clazz = sym.owner.enclClass - //Console.println("memberRef from "+currentClass+" to "+sym+" in "+clazz) - def prematureSelfReference() { + // println(s"memberRef from $currentClass to $sym in $clazz (currentClass=$currentClass)") + def prematureSelfReference(): Tree = { val what = if (clazz.isStaticOwner) clazz.fullLocationString else s"the unconstructed `this` of ${clazz.fullLocationString}" val msg = s"Implementation restriction: access of ${sym.fullLocationString} from ${currentClass.fullLocationString}, would require illegal premature access to $what" reporter.error(curTree.pos, msg) + EmptyTree } - val qual = + def qual = if (clazz == currentClass) gen.mkAttributedThis(clazz) else { sym resetFlag (LOCAL | PRIVATE) - if (isUnderConstruction(clazz)) { - prematureSelfReference() - EmptyTree - } + if (isUnderConstruction(clazz)) prematureSelfReference() else if (clazz.isStaticOwner) gen.mkAttributedQualifier(clazz.thisType) - else { - outerValue match { - case EmptyTree => prematureSelfReference(); return EmptyTree - case o => outerPath(o, currentClass.outerClass, clazz) - } + else outerValue match { + case EmptyTree => prematureSelfReference() + case o => outerPath(o, currentClass.outerClass, clazz) } } - Select(qual, sym) setType sym.tpe + + qual match { + case EmptyTree => EmptyTree + case qual => Select(qual, sym) setType sym.tpe + } } private def proxyRef(sym: Symbol) = { @@ -374,41 +377,45 @@ abstract class LambdaLift extends InfoTransform { if (psym.isLocalToBlock) gen.mkAttributedIdent(psym) else memberRef(psym) } - private def addFreeArgs(pos: Position, sym: Symbol, args: List[Tree]) = { - free get sym match { - case Some(fvs) => addFree(sym, free = fvs.toList map (fv => atPos(pos)(proxyRef(fv))), original = args) - case _ => args + def freeArgsOrNil(sym: Symbol) = free.getOrElse(sym, Nil).toList + + private def freeArgs(sym: Symbol): List[Symbol] = + freeArgsOrNil(sym) + + private def addFreeArgs(pos: Position, sym: Symbol, args: List[Tree]) = + freeArgs(sym) match { + case Nil => args + case fvs => addFree(sym, free = fvs map (fv => atPos(pos)(proxyRef(fv))), original = args) } - } - private def addFreeParams(tree: Tree, sym: Symbol): Tree = proxies.get(sym) match { - case Some(ps) => - val freeParams = ps map (p => ValDef(p) setPos tree.pos setType NoType) - tree match { - case DefDef(_, _, _, vparams :: _, _, _) => - val addParams = cloneSymbols(ps).map(_.setFlag(PARAM)) - sym.updateInfo( - lifted(MethodType(addFree(sym, free = addParams, original = sym.info.params), sym.info.resultType))) + def proxiesOrNil(sym: Symbol) = proxies.getOrElse(sym, Nil) + + private def freeParams(sym: Symbol): List[Symbol] = + proxiesOrNil(sym) + + private def addFreeParams(tree: Tree, sym: Symbol): Tree = + tree match { + case DefDef(_, _, _, vparams :: _, _, _) => + val ps = freeParams(sym) + + if (ps isEmpty) tree + else { + val paramSyms = cloneSymbols(ps).map(_.setFlag(PARAM)) + val paramDefs = ps map (p => ValDef(p) setPos tree.pos setType NoType) + + sym.updateInfo(lifted(MethodType(addFree(sym, free = paramSyms, original = sym.info.params), sym.info.resultType))) + copyDefDef(tree)(vparamss = List(addFree(sym, free = paramDefs, original = vparams))) + } + + case ClassDef(_, _, _, _) => + val freeParamDefs = freeParams(sym) map (p => ValDef(p) setPos tree.pos setType NoType) + + if (freeParamDefs isEmpty) tree + else deriveClassDef(tree)(impl => deriveTemplate(impl)(_ ::: freeParamDefs)) + + case _ => tree + } - copyDefDef(tree)(vparamss = List(addFree(sym, free = freeParams, original = vparams))) - case ClassDef(_, _, _, _) => - // SI-6231 - // Disabled attempt to to add getters to freeParams - // this does not work yet. Problem is that local symbols need local names - // and references to local symbols need to be transformed into - // method calls to setters. - // def paramGetter(param: Symbol): Tree = { - // val getter = param.newGetter setFlag TRANS_FLAG resetFlag PARAMACCESSOR // mark because we have to add them to interface - // sym.info.decls.enter(getter) - // val rhs = Select(gen.mkAttributedThis(sym), param) setType param.tpe - // DefDef(getter, rhs) setPos tree.pos setType NoType - // } - // val newDefs = if (sym.isTrait) freeParams ::: (ps map paramGetter) else freeParams - deriveClassDef(tree)(impl => deriveTemplate(impl)(_ ::: freeParams)) - } - case None => - tree - } /* SI-6231: Something like this will be necessary to eliminate the implementation * restriction from paramGetter above: @@ -451,7 +458,7 @@ abstract class LambdaLift extends InfoTransform { // See neg/t1909-object.scala def msg = s"SI-1909 Unable to STATICally lift $sym, which is defined in the self- or super-constructor call of ${sym.owner.owner}. A VerifyError is likely." devWarning(tree.pos, msg) - } else sym setFlag STATIC + } else sym setFlag STATIC } sym.owner = sym.owner.enclClass @@ -468,12 +475,11 @@ abstract class LambdaLift extends InfoTransform { private def postTransform(tree: Tree, isBoxedRef: Boolean = false): Tree = { val sym = tree.symbol tree match { - case ClassDef(_, _, _, _) => - val tree1 = addFreeParams(tree, sym) - if (sym.isLocalToBlock) liftDef(tree1) else tree1 - case DefDef(_, _, _, _, _, _) => - val tree1 = addFreeParams(tree, sym) - if (sym.isLocalToBlock) liftDef(tree1) else tree1 + case _: ClassDef | _: DefDef => + val withFreeParams = addFreeParams(tree, sym) + if (sym.isLocalToBlock) liftDef(withFreeParams) + else withFreeParams + case ValDef(mods, name, tpt, rhs) => if (sym.isCapturedVariable) { val tpt1 = TypeTree(sym.tpe) setPos tpt.pos diff --git a/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala b/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala index e0d96df062..d237ccbb96 100644 --- a/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala +++ b/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala @@ -287,7 +287,7 @@ abstract class SuperAccessors extends transform.Transform with transform.TypingT val result = (localTyper.typedPos(tree.pos) { Select(Super(qual, tpnme.EMPTY) setPos qual.pos, sym.alias) }).asInstanceOf[Select] - debuglog("alias replacement: " + tree + " ==> " + result); //debug + debuglog(s"alias replacement: $sym --> ${sym.alias} / $tree ==> $result"); //debug localTyper.typed(gen.maybeMkAsInstanceOf(transformSuperSelect(result), sym.tpe, sym.alias.tpe, beforeRefChecks = true)) } else { /* |