aboutsummaryrefslogtreecommitdiff
path: root/jni-plugin/src/main/scala/ch/jodersky/sbt/jni/util/ByteCode.scala
diff options
context:
space:
mode:
authorJakob Odersky <jodersky@gmail.com>2015-12-06 17:03:08 -0800
committerJakob Odersky <jodersky@gmail.com>2015-12-06 17:09:40 -0800
commite2505d1d9e2e49554057a8cd5fb71b0ac0e3ba63 (patch)
treef4fec79ba707aa9b2dec903d54a164f357961f19 /jni-plugin/src/main/scala/ch/jodersky/sbt/jni/util/ByteCode.scala
parent3e90312b3f2d912bf27e91b454a6ef21a81a2fc5 (diff)
downloadsbt-jni-e2505d1d9e2e49554057a8cd5fb71b0ac0e3ba63.tar.gz
sbt-jni-e2505d1d9e2e49554057a8cd5fb71b0ac0e3ba63.tar.bz2
sbt-jni-e2505d1d9e2e49554057a8cd5fb71b0ac0e3ba63.zip
Use separate project for native libraries
Diffstat (limited to 'jni-plugin/src/main/scala/ch/jodersky/sbt/jni/util/ByteCode.scala')
-rw-r--r--jni-plugin/src/main/scala/ch/jodersky/sbt/jni/util/ByteCode.scala57
1 files changed, 57 insertions, 0 deletions
diff --git a/jni-plugin/src/main/scala/ch/jodersky/sbt/jni/util/ByteCode.scala b/jni-plugin/src/main/scala/ch/jodersky/sbt/jni/util/ByteCode.scala
new file mode 100644
index 0000000..308a077
--- /dev/null
+++ b/jni-plugin/src/main/scala/ch/jodersky/sbt/jni/util/ByteCode.scala
@@ -0,0 +1,57 @@
+package ch.jodersky.sbt.jni
+package util
+
+import java.io.{File, FileInputStream, Closeable}
+import scala.collection.mutable.{HashSet}
+
+import org.objectweb.asm.{ClassReader, ClassVisitor, MethodVisitor, Opcodes}
+
+object ByteCode {
+
+ private class NativeFinder extends ClassVisitor(Opcodes.ASM5) {
+
+ //contains any classes found to contain at least one @native def
+ val _nativeClasses = new HashSet[String]
+ def nativeClasses = _nativeClasses.toSet
+
+ private var fullyQualifiedName: String = ""
+
+ override def visit(version: Int, access: Int, name: String, signature: String,
+ superName: String, interfaces: Array[String]): Unit = {
+ fullyQualifiedName = name.replaceAll("/", ".")
+ }
+
+ override def visitMethod(access: Int, name: String, desc: String,
+ signature: String, exceptions: Array[String]): MethodVisitor = {
+
+ val isNative = (access & Opcodes.ACC_NATIVE) != 0
+
+ if (isNative) {
+ _nativeClasses += fullyQualifiedName
+ }
+
+ null //do not visit method further
+ }
+
+ }
+
+ private def using[A >: Null <: Closeable, R](mkStream: => A)(action: A => R): R = {
+ var stream: A = null
+ try {
+ stream = mkStream
+ action(stream)
+ } finally {
+ if (stream != null) {
+ stream.close()
+ }
+ }
+ }
+
+ def natives(classFile: File): Set[String] = using(new FileInputStream(classFile)) { in =>
+ val reader = new ClassReader(in)
+ val finder = new NativeFinder
+ reader.accept(finder, 0)
+ finder.nativeClasses
+ }
+
+}