summaryrefslogtreecommitdiff
path: root/src/partest
diff options
context:
space:
mode:
authorJason Zaugg <jzaugg@gmail.com>2013-06-06 19:01:48 +0200
committerJason Zaugg <jzaugg@gmail.com>2013-06-06 19:01:48 +0200
commit2a19cd56258884e25f26565d7b865cc2ec931b23 (patch)
tree699ce548bdc6a2cd63b4a4ab448036681bc7a2f8 /src/partest
parent5312d6305530eb14d369d0f4acaf7ca4e278ea72 (diff)
downloadscala-2a19cd56258884e25f26565d7b865cc2ec931b23.tar.gz
scala-2a19cd56258884e25f26565d7b865cc2ec931b23.tar.bz2
scala-2a19cd56258884e25f26565d7b865cc2ec931b23.zip
SI-2464 Resiliance against missing InnerClass attributes
A classfile in the wild related to Vaadin lacked the InnerClasses attribute. As such, our class file parser treated a nested enum class as top-level, which led to a crash when trying to find its linked module. More details of the investigation are available in the JIRA comments. The test introduces a new facility to rewrite classfiles. This commit turns this situation into a logged warning, rather than crashing. Code by @paulp, test by yours truly.
Diffstat (limited to 'src/partest')
-rw-r--r--src/partest/scala/tools/partest/BytecodeTest.scala35
1 files changed, 31 insertions, 4 deletions
diff --git a/src/partest/scala/tools/partest/BytecodeTest.scala b/src/partest/scala/tools/partest/BytecodeTest.scala
index 2699083069..172fa29189 100644
--- a/src/partest/scala/tools/partest/BytecodeTest.scala
+++ b/src/partest/scala/tools/partest/BytecodeTest.scala
@@ -2,10 +2,9 @@ package scala.tools.partest
import scala.tools.nsc.util.JavaClassPath
import scala.collection.JavaConverters._
-import scala.tools.asm
-import asm.{ ClassReader }
-import asm.tree.{ClassNode, MethodNode, InsnList}
-import java.io.InputStream
+import scala.tools.asm.{ClassWriter, ClassReader}
+import scala.tools.asm.tree.{ClassNode, MethodNode, InsnList}
+import java.io.{FileOutputStream, FileInputStream, File => JFile, InputStream}
import AsmNode._
/**
@@ -127,3 +126,31 @@ abstract class BytecodeTest extends ASMConverters {
new JavaClassPath(containers, DefaultJavaContext)
}
}
+
+object BytecodeTest {
+ /** Parse `file` as a class file, transforms the ASM representation with `f`,
+ * and overwrites the orginal file.
+ */
+ def modifyClassFile(file: JFile)(f: ClassNode => ClassNode) {
+ val rfile = new reflect.io.File(file)
+ def readClass: ClassNode = {
+ val cr = new ClassReader(rfile.toByteArray())
+ val cn = new ClassNode()
+ cr.accept(cn, 0)
+ cn
+ }
+
+ def writeClass(cn: ClassNode) {
+ val writer = new ClassWriter(0)
+ cn.accept(writer)
+ val os = rfile.bufferedOutput()
+ try {
+ os.write(writer.toByteArray)
+ } finally {
+ os.close()
+ }
+ }
+
+ writeClass(f(readClass))
+ }
+}