Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions build.sbt
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
name := "recursivity-commons"

version := "0.6"

organization := "com.recursivity"

scalaVersion := "2.10.4"

//artifact-name := "bingo"

resolvers ++= Seq(
"Sonatype OSS Snapshots" at "http://oss.sonatype.org/content/repositories/snapshots/",
"Sonatype OSS Releases" at "https://oss.sonatype.org/content/repositories/releases",
"Novus Salat Snapshots" at "http://repo.novus.com/snapshots",
"Scala-Tools repo" at "http://scala-tools.org/repo-releases/",
"Spring Repo" at "http://maven.springframework.org/milestone",
"Buzz Media" at "http://maven.thebuzzmedia.com",
"Codahale" at "http://repo.codahale.com"
)

resolvers += "Local Maven Repository" at "file://"+Path.userHome.absolutePath+"/.m2/repository"

libraryDependencies += "org.scalatest" %% "scalatest" % "2.2.4" % "test"

libraryDependencies += "org.scala-lang" % "scalap" % "2.10.4"

libraryDependencies += "org.scala-lang" % "scala-reflect" % "2.10.4"
4 changes: 2 additions & 2 deletions project/build.properties
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
#Sat Apr 30 19:45:58 BST 2011
project.organization=com.recursivity
project.name=recursivity-commons
sbt.version=0.7.7
sbt.version=0.13.5
project.version=0.6
build.scala.versions=2.9.1
build.scala.versions=2.10.4
project.initialize=false
8 changes: 4 additions & 4 deletions src/main/scala/com/recursivity/commons/bean/BeanUtils.scala
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ object BeanUtils {
}catch{
case e: InstantiationException => l = new java.util.ArrayList[Any]
}
list.foreach(b => l.add(b))
list.asInstanceOf[List[Any]].foreach(b => l.add(b))
return l
}
}
Expand Down Expand Up @@ -187,17 +187,17 @@ object BeanUtils {
val listOrSet = cls.newInstance
if (classOf[Builder[Any, Any]].isAssignableFrom(cls)) {
val builder = listOrSet.asInstanceOf[Builder[Any, Any]]
list.foreach(b => builder += b)
list.asInstanceOf[List[Any]].foreach(b => builder += b)
return builder
} else if (classOf[LinkedList[_]].isAssignableFrom(cls)) {
var seq = listOrSet.asInstanceOf[LinkedList[_]]
list.foreach(elem => {
list.asInstanceOf[List[Any]].foreach(elem => {
seq = seq :+ elem
})
return seq
} else if (classOf[DoubleLinkedList[_]].isAssignableFrom(cls)) {
var seq = listOrSet.asInstanceOf[DoubleLinkedList[_]]
list.foreach(elem => {
list.asInstanceOf[List[Any]].foreach(elem => {
seq = seq :+ elem
})
return seq
Expand Down
Original file line number Diff line number Diff line change
@@ -1,64 +1,93 @@
package com.recursivity.commons.bean.scalap

import scala.tools.scalap.scalax.rules.scalasig._


import tools.scalap._
import scalax.rules.scalasig.ClassFileParser.{ConstValueIndex, Annotation}
import reflect.generic.ByteCodecs
import java.io.{StringWriter, ByteArrayOutputStream, PrintStream}
import java.io.{StringWriter, PrintStream, OutputStreamWriter, ByteArrayOutputStream}
import scala.reflect.NameTransformer
import scala.tools.scalap._
import scalax.rules.scalasig._

/**
* This file is largely an extended retro-fit of scala.tools.scalap.Main from the scalap.jar of the Scala
* distribution, hence copyrights and kudos to all the people involved in that. I have merely made it slightly more
* usable within an application context, rather than as a command line tool, and added functions for parsing the output.
*
* Scala classfile decoder
* c) 2003-2010, LAMP/EPFL
* http://scala-lang.org/
*
* @author Matthias Zenger, Stephane Micheloud, Burak Emir, Ilya Sergey, Wille Faler
*/
* This file is largely an extended retro-fit of scala.tools.scalap.Main from the scalap.jar of the Scala
* distribution, hence copyrights and kudos to all the people involved in that. I have merely made it slightly more
* usable within an application context, rather than as a command line tool, and added functions for parsing the output.
*
* Scala classfile decoder
* c) 2003-2010, LAMP/EPFL
* http://scala-lang.org/
*
* @author Matthias Zenger, Stephane Micheloud, Burak Emir, Ilya Sergey, Wille Faler
*/
object ScalaSigParser {

val SCALA_SIG = "ScalaSig"
val SCALA_SIG = "ScalaSig"
val SCALA_SIG_ANNOTATION = "Lscala/reflect/ScalaSignature;"
val BYTES_VALUE = "bytes"
val BYTES_VALUE = "bytes"

/* val versionMsg = "Scala classfile decoder " +
Properties.versionString + " -- " +
/* val versionMsg = "Scala classfile decoder " +
Properties.versionString + " -- " +
Properties.copyrightString + "\n" */

var printPrivates = false

def isScalaFile(bytes: Array[Byte]): Boolean = {
val byteCode = ByteCode(bytes)
val classFile = ClassFileParser.parse(byteCode)
classFile.attribute("ScalaSig").isDefined
}

def processJavaClassFile(clazz: Classfile): String = {
/**Processes the given Java class file.
*
* @param clazz the class file to be processed.
*/
def processJavaClassFile(clazz: Classfile) = {
val out = new StringWriter
/// / construct a new output stream writer
//val out = new OutputStreamWriter(Console.out)
val writer = new JavaWriter(clazz, out)
// print the class
writer.printClass
out.flush()
return writer.toString
writer.toString()
}

def process(classname: String): String = {
val encName = Names.encode(
if (classname == "scala.AnyRef") "java.lang.Object"
else classname)
val name = "/" + encName.replace(".", "/") + ".class"
val resource = this.getClass.getResourceAsStream(name)
def isPackageObjectFile(s: String) = s != null && (s.endsWith(".package") || s == "package")

val bytes = readToBytes(resource)
def parseScalaSignature(scalaSig: ScalaSig, isPackageObject: Boolean) = {
val baos = new ByteArrayOutputStream
val stream = new PrintStream(baos)
val syms = scalaSig.topLevelClasses ++ scalaSig.topLevelObjects

if (isScalaFile(bytes)) {
return decompileScala(bytes, isPackageObjectFile(classname))
} else {
// construct a reader for the classfile content
val reader = new ByteArrayReader(bytes) //cfile.toByteArray)
// parse the classfile
val clazz = new Classfile(reader)
return processJavaClassFile(clazz)
syms.head.parent match {
// Partial match
case Some(p) if (p.name != "<empty>") => {
val path = p.path
if (!isPackageObject) {
stream.print("package ");
stream.print(path);
stream.print("\n")
} else {
val i = path.lastIndexOf(".")
if (i > 0) {
stream.print("package ");
stream.print(path.substring(0, i))
stream.print("\n")
}
}
}
case _ =>
}
// Print classes
val printer = new ScalaSigPrinter(stream, printPrivates)
syms foreach (printer printSymbol _)
baos.toString
}

def decompileScala(bytes: Array[Byte], isPackageObject: Boolean): String = {
val byteCode = ByteCode(bytes)
val classFile = ClassFileParser.parse(byteCode)

scala.tools.scalap.scalax.rules.scalasig.ScalaSigParser.parse(classFile) match {
case Some(scalaSig) => parseScalaSignature(scalaSig, isPackageObject)
case None => ""
}
}

Expand All @@ -79,71 +108,36 @@ object ScalaSigParser {
bytes
}

def isPackageObjectFile(s: String) = s != null && (s.endsWith(".package") || s == "package")


def decompileScala(bytes: Array[Byte], isPackageObject: Boolean): String = {
val byteCode = ByteCode(bytes)
val classFile = ClassFileParser.parse(byteCode)
classFile.attribute(SCALA_SIG).map(_.byteCode).map(ScalaSigAttributeParsers.parse) match {
// No entries in ScalaSig attribute implies that the signature is stored in the annotation
case Some(ScalaSig(_, _, entries)) if entries.length == 0 => unpickleFromAnnotation(classFile, isPackageObject)
case Some(scalaSig) => parseScalaSignature(scalaSig, isPackageObject)
case None => ""
/** Executes scalap with the given arguments and classpath for the
* class denoted by `classname`.
*/
def process(classname: String) = {
// find the classfile
val encName = classname match {
case "scala.AnyRef" => "java.lang.Object"
case _ =>
// we have to encode every fragment of a name separately, otherwise the NameTransformer
// will encode using unicode escaping dot separators as well
// we can afford allocations because this is not a performance critical code
classname.split('.').map(NameTransformer.encode).mkString(".")
}
}

def isScalaFile(bytes: Array[Byte]): Boolean = {
val byteCode = ByteCode(bytes)
val classFile = ClassFileParser.parse(byteCode)
classFile.attribute("ScalaSig").isDefined
}
val name = "/" + encName.replace(".", "/") + ".class"
val resource = this.getClass.getResourceAsStream(name)
val bytes = readToBytes(resource)

def unpickleFromAnnotation(classFile: ClassFile, isPackageObject: Boolean): String = {
import classFile._
classFile.annotation(SCALA_SIG_ANNOTATION) match {
case None => ""
case Some(Annotation(_, elements)) =>
val bytesElem = elements.find(elem => constant(elem.elementNameIndex) == BYTES_VALUE).get
val bytes = ((bytesElem.elementValue match {
case ConstValueIndex(index) => constantWrapped(index)
})
.asInstanceOf[StringBytesPair].bytes)
val length = ByteCodecs.decode(bytes)
val scalaSig = ScalaSigAttributeParsers.parse(ByteCode(bytes.take(length)))
parseScalaSignature(scalaSig, isPackageObject)
if (isScalaFile(bytes)) {
decompileScala(bytes, isPackageObjectFile(encName))
} else {
// construct a reader for the classfile content
val reader = new ByteArrayReader(bytes)
// parse the classfile
val clazz = new Classfile(reader)
processJavaClassFile(clazz)
}
}

def parseScalaSignature(scalaSig: ScalaSig, isPackageObject: Boolean) = {
val baos = new ByteArrayOutputStream
val stream = new PrintStream(baos)
val syms = scalaSig.topLevelClasses ::: scalaSig.topLevelObjects
syms.head.parent match {
//Partial match
case Some(p) if (p.name != "<empty>") => {
val path = p.path
if (!isPackageObject) {
stream.print("package ");
stream.print(path);
stream.print("\n")
} else {
val i = path.lastIndexOf(".")
if (i > 0) {
stream.print("package ");
stream.print(path.substring(0, i))
stream.print("\n")
}
}
}
case _ =>
}
// Print classes
val printer = new ScalaSigPrinter(stream, printPrivates)
for (c <- syms) {
printer.printSymbol(c)
}
baos.toString
}

}