summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorSom Snytt <som.snytt@gmail.com>2014-10-04 12:33:11 -0700
committerSom Snytt <som.snytt@gmail.com>2014-10-06 08:00:22 -0700
commit964a197cd90e561d05c9d725cc13895f18b6a6d0 (patch)
tree51a80e3c486ad12b6b4f97920c696bdf167d54b4 /test
parent7b2c3cb8bb0f5f96f3182f551eb82cb1c59d460c (diff)
downloadscala-964a197cd90e561d05c9d725cc13895f18b6a6d0.tar.gz
scala-964a197cd90e561d05c9d725cc13895f18b6a6d0.tar.bz2
scala-964a197cd90e561d05c9d725cc13895f18b6a6d0.zip
SI-8843 AbsFileCL acts like a CL
Let the AbstractFileClassLoader override just the usual suspects. Normal delegation behavior should ensue. That's instead of overriding `getResourceAsStream`, which was intended that "The repl classloader now works more like you'd expect a classloader to." (Workaround for "Don't know how to construct an URL for something which exists only in memory.") Also override `findResources` so that `getResources` does the obvious thing, namely, return one iff `getResource` does. The translating class loader for REPL only special-cases `foo.class`: as a fallback, take `foo` as `$line42.$read$something$foo` and try that class file. That's the use case for "works like you'd expect it to." There was a previous fix to ensure `getResource` doesn't take a class name. The convenience behavior, that `classBytes` takes either a class name or a resource path ending in ".class", has been promoted to `ScalaClassLoader`.
Diffstat (limited to 'test')
-rw-r--r--test/files/run/t8843-repl-xlat.scala33
-rw-r--r--test/junit/scala/reflect/internal/PrintersTest.scala6
-rw-r--r--test/junit/scala/reflect/internal/util/AbstractFileClassLoaderTest.scala138
3 files changed, 174 insertions, 3 deletions
diff --git a/test/files/run/t8843-repl-xlat.scala b/test/files/run/t8843-repl-xlat.scala
new file mode 100644
index 0000000000..6426dbe7d4
--- /dev/null
+++ b/test/files/run/t8843-repl-xlat.scala
@@ -0,0 +1,33 @@
+
+import scala.tools.partest.SessionTest
+
+// Handy hamburger helper for repl resources
+object Test extends SessionTest {
+ def session =
+"""Type in expressions to have them evaluated.
+Type :help for more information.
+
+scala> $intp.isettings.unwrapStrings = false
+$intp.isettings.unwrapStrings: Boolean = false
+
+scala> class Bippy
+defined class Bippy
+
+scala> $intp.classLoader getResource "Bippy.class"
+res0: java.net.URL = memory:(memory)/$line4/$read$$iw$$iw$Bippy.class
+
+scala> ($intp.classLoader getResources "Bippy.class").nextElement
+res1: java.net.URL = memory:(memory)/$line4/$read$$iw$$iw$Bippy.class
+
+scala> ($intp.classLoader classBytes "Bippy").nonEmpty
+res2: Boolean = true
+
+scala> ($intp.classLoader classAsStream "Bippy") != null
+res3: Boolean = true
+
+scala> $intp.classLoader getResource "Bippy"
+res4: java.net.URL = null
+
+scala> :quit"""
+}
+
diff --git a/test/junit/scala/reflect/internal/PrintersTest.scala b/test/junit/scala/reflect/internal/PrintersTest.scala
index 1458b942dc..ca9b4671b2 100644
--- a/test/junit/scala/reflect/internal/PrintersTest.scala
+++ b/test/junit/scala/reflect/internal/PrintersTest.scala
@@ -24,10 +24,10 @@ object PrinterHelper {
resultCode.lines mkString s"$LF"
def assertResultCode(code: String)(parsedCode: String = "", typedCode: String = "", wrap: Boolean = false, printRoot: Boolean = false) = {
- def toolboxTree(tree: => Tree) = try{
+ def toolboxTree(tree: => Tree) = try {
tree
} catch {
- case e:scala.tools.reflect.ToolBoxError => throw new Exception(e.getMessage + ": " + code)
+ case e:scala.tools.reflect.ToolBoxError => throw new Exception(e.getMessage + ": " + code, e)
}
def wrapCode(source: String) = {
@@ -1186,4 +1186,4 @@ trait QuasiTreesPrintTests {
| };
| ()
|}""")
-} \ No newline at end of file
+}
diff --git a/test/junit/scala/reflect/internal/util/AbstractFileClassLoaderTest.scala b/test/junit/scala/reflect/internal/util/AbstractFileClassLoaderTest.scala
new file mode 100644
index 0000000000..a2537ddab7
--- /dev/null
+++ b/test/junit/scala/reflect/internal/util/AbstractFileClassLoaderTest.scala
@@ -0,0 +1,138 @@
+package scala.reflect.internal.util
+
+import org.junit.Assert._
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+
+@RunWith(classOf[JUnit4])
+class AbstractFileClassLoaderTest {
+
+ import scala.reflect.io._
+ import scala.io.Source
+ import scala.io.Codec.UTF8
+ import scala.reflect.io.Streamable
+ import java.net.{ URLClassLoader, URL }
+
+ implicit def `we love utf8` = UTF8
+ implicit class `abs file ops`(f: AbstractFile) {
+ def writeContent(s: String): Unit = Streamable.closing(f.bufferedOutput)(os => os write s.getBytes(UTF8.charSet))
+ }
+ implicit class `url slurp`(url: URL) {
+ def slurp(): String = Streamable.slurp(url)
+ }
+
+ val NoClassLoader: ClassLoader = null
+
+ def fuzzBuzzBooz: (AbstractFile, AbstractFile) = {
+ val fuzz = new VirtualDirectory("fuzz", None)
+ val buzz = fuzz subdirectoryNamed "buzz"
+ val booz = buzz fileNamed "booz.class"
+ (fuzz, booz)
+ }
+
+ @Test
+ def afclGetsParent(): Unit = {
+ val p = new URLClassLoader(Array.empty[URL])
+ val d = new VirtualDirectory("vd", None)
+ val x = new AbstractFileClassLoader(d, p)
+ assertSame(p, x.getParent)
+ }
+
+ @Test
+ def afclGetsResource(): Unit = {
+ val (fuzz, booz) = fuzzBuzzBooz
+ booz writeContent "hello, world"
+ val x = new AbstractFileClassLoader(fuzz, NoClassLoader)
+ val r = x.getResource("buzz/booz.class")
+ assertNotNull(r)
+ assertEquals("hello, world", r.slurp())
+ }
+
+ @Test
+ def afclGetsResourceFromParent(): Unit = {
+ val (fuzz, booz) = fuzzBuzzBooz
+ val (fuzz_, booz_) = fuzzBuzzBooz
+ booz writeContent "hello, world"
+ booz_ writeContent "hello, world_"
+ val p = new AbstractFileClassLoader(fuzz, NoClassLoader)
+ val x = new AbstractFileClassLoader(fuzz_, p)
+ val r = x.getResource("buzz/booz.class")
+ assertNotNull(r)
+ assertEquals("hello, world", r.slurp())
+ }
+
+ @Test
+ def afclGetsResourceInDefaultPackage(): Unit = {
+ val fuzz = new VirtualDirectory("fuzz", None)
+ val booz = fuzz fileNamed "booz.class"
+ val bass = fuzz fileNamed "bass"
+ booz writeContent "hello, world"
+ bass writeContent "lo tone"
+ val x = new AbstractFileClassLoader(fuzz, NoClassLoader)
+ val r = x.getResource("booz.class")
+ assertNotNull(r)
+ assertEquals("hello, world", r.slurp())
+ assertEquals("lo tone", (x getResource "bass").slurp())
+ }
+
+ // SI-8843
+ @Test
+ def afclGetsResources(): Unit = {
+ val (fuzz, booz) = fuzzBuzzBooz
+ booz writeContent "hello, world"
+ val x = new AbstractFileClassLoader(fuzz, NoClassLoader)
+ val e = x.getResources("buzz/booz.class")
+ assertTrue(e.hasMoreElements)
+ assertEquals("hello, world", e.nextElement.slurp())
+ assertFalse(e.hasMoreElements)
+ }
+
+ @Test
+ def afclGetsResourcesFromParent(): Unit = {
+ val (fuzz, booz) = fuzzBuzzBooz
+ val (fuzz_, booz_) = fuzzBuzzBooz
+ booz writeContent "hello, world"
+ booz_ writeContent "hello, world_"
+ val p = new AbstractFileClassLoader(fuzz, NoClassLoader)
+ val x = new AbstractFileClassLoader(fuzz_, p)
+ val e = x.getResources("buzz/booz.class")
+ assertTrue(e.hasMoreElements)
+ assertEquals("hello, world", e.nextElement.slurp())
+ assertTrue(e.hasMoreElements)
+ assertEquals("hello, world_", e.nextElement.slurp())
+ assertFalse(e.hasMoreElements)
+ }
+
+ @Test
+ def afclGetsResourceAsStream(): Unit = {
+ val (fuzz, booz) = fuzzBuzzBooz
+ booz writeContent "hello, world"
+ val x = new AbstractFileClassLoader(fuzz, NoClassLoader)
+ val r = x.getResourceAsStream("buzz/booz.class")
+ assertNotNull(r)
+ assertEquals("hello, world", Streamable.closing(r)(is => Source.fromInputStream(is).mkString))
+ }
+
+ @Test
+ def afclGetsClassBytes(): Unit = {
+ val (fuzz, booz) = fuzzBuzzBooz
+ booz writeContent "hello, world"
+ val x = new AbstractFileClassLoader(fuzz, NoClassLoader)
+ val b = x.classBytes("buzz/booz.class")
+ assertEquals("hello, world", new String(b, UTF8.charSet))
+ }
+
+ @Test
+ def afclGetsClassBytesFromParent(): Unit = {
+ val (fuzz, booz) = fuzzBuzzBooz
+ val (fuzz_, booz_) = fuzzBuzzBooz
+ booz writeContent "hello, world"
+ booz_ writeContent "hello, world_"
+
+ val p = new AbstractFileClassLoader(fuzz, NoClassLoader)
+ val x = new AbstractFileClassLoader(fuzz_, p)
+ val b = x.classBytes("buzz/booz.class")
+ assertEquals("hello, world", new String(b, UTF8.charSet))
+ }
+}