diff options
author | Jason Zaugg <jzaugg@gmail.com> | 2015-11-13 13:42:00 +1000 |
---|---|---|
committer | Jason Zaugg <jzaugg@gmail.com> | 2015-11-13 13:42:00 +1000 |
commit | 0c597f00390ff1ad5de113f9d33c6a88238732d9 (patch) | |
tree | ebabda98fb84213c96b11efe529ecceb0fa4c84b | |
parent | 9cdfc456853b5a4f8c985413865fc0719cf009f4 (diff) | |
parent | b237fb30554dbd3846193aae2c3ffe8bdb359c79 (diff) | |
download | scala-0c597f00390ff1ad5de113f9d33c6a88238732d9.tar.gz scala-0c597f00390ff1ad5de113f9d33c6a88238732d9.tar.bz2 scala-0c597f00390ff1ad5de113f9d33c6a88238732d9.zip |
Merge pull request #4809 from wpopielarski/delambdafy-multiple-outputs
Multi output problem with delambdafied compilation
3 files changed, 78 insertions, 5 deletions
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/BCodeHelpers.scala b/src/compiler/scala/tools/nsc/backend/jvm/BCodeHelpers.scala index 65a6b82570..1b97681743 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/BCodeHelpers.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/BCodeHelpers.scala @@ -35,15 +35,14 @@ abstract class BCodeHelpers extends BCodeIdiomatic with BytecodeWriters { /* * must-single-thread */ - def getOutFolder(csym: Symbol, cName: String, cunit: CompilationUnit): _root_.scala.tools.nsc.io.AbstractFile = { - try { + def getOutFolder(csym: Symbol, cName: String, cunit: CompilationUnit): _root_.scala.tools.nsc.io.AbstractFile = + _root_.scala.util.Try { outputDirectory(csym) - } catch { + }.recover { case ex: Throwable => reporter.error(cunit.body.pos, s"Couldn't create file for class $cName\n${ex.getMessage}") null - } - } + }.get var pickledBytes = 0 // statistics diff --git a/src/compiler/scala/tools/nsc/transform/Delambdafy.scala b/src/compiler/scala/tools/nsc/transform/Delambdafy.scala index ea8c1cbaf6..8e323de623 100644 --- a/src/compiler/scala/tools/nsc/transform/Delambdafy.scala +++ b/src/compiler/scala/tools/nsc/transform/Delambdafy.scala @@ -294,6 +294,7 @@ abstract class Delambdafy extends Transform with TypingTransformers with ast.Tre val name = unit.freshTypeName(s"$oldClassPart$suffix".replace("$anon", "$nestedInAnon")) val lambdaClass = pkg newClassSymbol(name, originalFunction.pos, FINAL | SYNTHETIC) addAnnotation SerialVersionUIDAnnotation + lambdaClass.associatedFile = unit.source.file // make sure currentRun.compiles(lambdaClass) is true (AddInterfaces does the same for trait impl classes) currentRun.symSource(lambdaClass) = funOwner.sourceFile lambdaClass setInfo ClassInfoType(parents, newScope, lambdaClass) diff --git a/test/junit/scala/tools/nsc/transform/delambdafy/DelambdafyTest.scala b/test/junit/scala/tools/nsc/transform/delambdafy/DelambdafyTest.scala new file mode 100644 index 0000000000..010078e28a --- /dev/null +++ b/test/junit/scala/tools/nsc/transform/delambdafy/DelambdafyTest.scala @@ -0,0 +1,73 @@ +package scala.tools.nsc.transform.delambdafy + +import scala.reflect.io.Path.jfile2path +import scala.tools.nsc.backend.jvm.CodeGenTools.getGeneratedClassfiles +import scala.tools.nsc.backend.jvm.CodeGenTools.makeSourceFile +import scala.tools.nsc.backend.jvm.CodeGenTools.newCompilerWithoutVirtualOutdir +import scala.tools.nsc.io.AbstractFile +import scala.tools.testing.TempDir + +import org.junit.Assert.assertTrue +import org.junit.Test +import org.junit.runner.RunWith +import org.junit.runners.JUnit4 + +@RunWith(classOf[JUnit4]) +class DelambdafyTest { + def compileToMultipleOutputWithDelamdbafyMethod(): List[(String, Array[Byte])] = { + val codeForMultiOutput = """ +object Delambdafy { + type -->[D, I] = PartialFunction[D, I] + + def main(args: Array[String]): Unit = { + val result = List(1, 2, 4).map { a => + val list = List("1", "2", "3").map { _ + "test" } + list.find { _ == a.toString + "test" } + } + println(result) + lazy val _foo = foo(result) { + case x :: xs if x isDefined => x.get.length + case _ => 0 + } + println(_foo) + lazy val bar: Int => Int = { + case 2 => 23 + case _ => + val v = List(1).map { _ + 42 }.head + v + 31 + } + bar(3) + lazy val _baz = baz { + case 1 => + val local = List(1).map(_ + 1) + local.head + } + } + + def baz[T](f: Any --> Any): Any => Any = f + + def foo(b: List[Option[String]])(a: List[Option[String]] => Int): Int = a(b) +} +""" + val srcFile = makeSourceFile(codeForMultiOutput, "delambdafyTest.scala") + val outDir = AbstractFile.getDirectory(TempDir.createTempDir()) + val outDirPath = outDir.canonicalPath + val extraArgs = "-Ybackend:GenBCode -Ydelambdafy:method" + val argsWithOutDir = extraArgs + s" -d $outDirPath -cp $outDirPath" + val compiler = newCompilerWithoutVirtualOutdir(extraArgs = argsWithOutDir) + compiler.settings.outputDirs.add(srcFile.file, outDir) + + new compiler.Run().compileSources(List(srcFile)) + + val classfiles = getGeneratedClassfiles(outDir) + outDir.delete() + classfiles + } + + @Test + def shouldFindOutputFoldersForAllPromotedLambdasAsMethod(): Unit = { + val actual = compileToMultipleOutputWithDelamdbafyMethod() + + assertTrue(actual.length > 0) + } +} |