diff options
author | Adriaan Moors <adriaan.moors@typesafe.com> | 2016-03-21 21:03:11 -0700 |
---|---|---|
committer | Adriaan Moors <adriaan.moors@typesafe.com> | 2016-03-26 22:54:18 -0700 |
commit | b0b0abab89f0c40ba3c45b4a1f7bada31040d55a (patch) | |
tree | c98ae4100c042010e5178ec4d1ec15abf5a73b41 | |
parent | 49d946d9039a6240765abd26375883875e5ff7e8 (diff) | |
download | scala-b0b0abab89f0c40ba3c45b4a1f7bada31040d55a.tar.gz scala-b0b0abab89f0c40ba3c45b4a1f7bada31040d55a.tar.bz2 scala-b0b0abab89f0c40ba3c45b4a1f7bada31040d55a.zip |
Jason's review feedback (ThisReferringMethodTraverser)
- Re-simplify logging;
- Remove unused method valueTypeToObject;
- Limit ThisReferringMethodTraverser to material parts
of the AST
Limit ThisReferringMethodTraverser's analysis to only look at
template-owned anonfun method bodies, to make sure it's fairly
low overhead.
AFAICT, part of the complexity of this analysis stems from the
desire to make all the lambda impl methods static in
`() => () => 42`: https://gist.github.com/062181846c13e65490cc.
It would possible to accumulate the knowledge we need during the
main transform, rather than in an additional pass. We'd need to
transform template bodies in such a way that we we process
definitions of anonfun methods before usages, which would
currently amount to transforming the stats in reverse.
3 files changed, 13 insertions, 11 deletions
diff --git a/src/compiler/scala/tools/nsc/transform/Delambdafy.scala b/src/compiler/scala/tools/nsc/transform/Delambdafy.scala index 3262dd9202..0614b138a7 100644 --- a/src/compiler/scala/tools/nsc/transform/Delambdafy.scala +++ b/src/compiler/scala/tools/nsc/transform/Delambdafy.scala @@ -106,11 +106,7 @@ abstract class Delambdafy extends Transform with TypingTransformers with ast.Tre case _ => tp } - private def valueTypeToObject(tpe: Type): Type = - if (isPrimitiveValueClass(tpe.typeSymbol) || enteringErasure(tpe.typeSymbol.isDerivedValueClass)) ObjectTpe - else tpe - - // exclude primitives and value classses, which need special boxing + // exclude primitives and value classes, which need special boxing private def isReferenceType(tp: Type) = !tp.isInstanceOf[ErasedValueType] && { val sym = tp.typeSymbol !(isPrimitiveValueClass(sym) || sym.isDerivedValueClass) @@ -324,7 +320,7 @@ abstract class Delambdafy extends Transform with TypingTransformers with ast.Tre private var currentMethod: Symbol = NoSymbol override def traverse(tree: Tree) = tree match { - case DefDef(_, _, _, _, _, _) => + case DefDef(_, _, _, _, _, _) if tree.symbol.isDelambdafyTarget => // we don't expect defs within defs. At this phase trees should be very flat if (currentMethod.exists) devWarning("Found a def within a def at a phase where defs are expected to be flattened out.") currentMethod = tree.symbol @@ -340,6 +336,8 @@ abstract class Delambdafy extends Transform with TypingTransformers with ast.Tre debuglog(s"$currentMethod directly refers to 'this'") thisReferringMethods add currentMethod } + case _: ClassDef if !tree.symbol.isTopLevel => + case _: DefDef => case _ => super.traverse(tree) } diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index 4f006fe9a9..3b826ae2e5 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -1058,11 +1058,9 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper inferView(tree, tree.tpe, pt) match { case EmptyTree => // didn't find a view -- fall through case coercion => - if (settings.debug || settings.logImplicitConv) { - val msg = s"inferred view from ${tree.tpe} to $pt via $coercion: ${coercion.tpe}" - debuglog(msg) - if (settings.logImplicitConv) context.echo(tree.pos, msg) - } + def msg = s"inferred view from ${tree.tpe} to $pt via $coercion: ${coercion.tpe}" + if (settings.logImplicitConv) context.echo(tree.pos, msg) + else debuglog(msg) val silentContext = context.makeImplicit(context.ambiguousErrors) val res = newTyper(silentContext).typed( diff --git a/test/junit/scala/tools/nsc/backend/jvm/IndySammyTest.scala b/test/junit/scala/tools/nsc/backend/jvm/IndySammyTest.scala index 6f213e6625..f7218c576c 100644 --- a/test/junit/scala/tools/nsc/backend/jvm/IndySammyTest.scala +++ b/test/junit/scala/tools/nsc/backend/jvm/IndySammyTest.scala @@ -127,4 +127,10 @@ class IndySammyTest extends ClearAfterClass { List(Op(ICONST_1), Invoke(INVOKESTATIC, "scala/runtime/BoxesRunTime", "boxToInteger", "(I)Ljava/lang/Integer;", false)), Op(IRETURN))() + // Tests ThisReferringMethodsTraverser + @Test + def testStaticIfNoThisReference: Unit = { + val methodNodes = compileMethods(compiler)("def foo = () => () => () => 42") + methodNodes.forall(m => !m.name.contains("anonfun") || (m.access & ACC_STATIC) == ACC_STATIC) + } } |