summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdriaan Moors <adriaan.moors@typesafe.com>2016-03-21 21:03:11 -0700
committerAdriaan Moors <adriaan.moors@typesafe.com>2016-03-26 22:54:18 -0700
commitb0b0abab89f0c40ba3c45b4a1f7bada31040d55a (patch)
treec98ae4100c042010e5178ec4d1ec15abf5a73b41
parent49d946d9039a6240765abd26375883875e5ff7e8 (diff)
downloadscala-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.
-rw-r--r--src/compiler/scala/tools/nsc/transform/Delambdafy.scala10
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala8
-rw-r--r--test/junit/scala/tools/nsc/backend/jvm/IndySammyTest.scala6
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)
+ }
}