From b0b0abab89f0c40ba3c45b4a1f7bada31040d55a Mon Sep 17 00:00:00 2001 From: Adriaan Moors Date: Mon, 21 Mar 2016 21:03:11 -0700 Subject: 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. --- src/compiler/scala/tools/nsc/transform/Delambdafy.scala | 10 ++++------ src/compiler/scala/tools/nsc/typechecker/Typers.scala | 8 +++----- test/junit/scala/tools/nsc/backend/jvm/IndySammyTest.scala | 6 ++++++ 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) + } } -- cgit v1.2.3