From 52a647c94d67dfa39181c165cb9bef041ed1746c Mon Sep 17 00:00:00 2001 From: Antonio Cunei Date: Tue, 14 Sep 2010 18:34:51 +0000 Subject: Merged revisions 22669 via svnmerge from https://lampsvn.epfl.ch/svn-repos/scala/scala/trunk ........ r22669 | extempore | 2010-08-03 20:02:00 +0200 (Tue, 03 Aug 2010) | 2 lines Generalized the scala sig "look in both attribute and annotation" code so it can be reused outside of scalap main. Closes #3717, review by ilyas. ........ --- src/scalap/scala/tools/scalap/Main.scala | 23 ++-------- .../scalap/scalax/rules/scalasig/ScalaSig.scala | 50 +++++++++++++++------- 2 files changed, 37 insertions(+), 36 deletions(-) diff --git a/src/scalap/scala/tools/scalap/Main.scala b/src/scalap/scala/tools/scalap/Main.scala index 88b6c53c46..c2b9324ba9 100644 --- a/src/scalap/scala/tools/scalap/Main.scala +++ b/src/scalap/scala/tools/scalap/Main.scala @@ -10,12 +10,10 @@ package scala.tools.scalap import java.io.{PrintStream, OutputStreamWriter, ByteArrayOutputStream} import scalax.rules.scalasig._ -import scalax.rules.scalasig.ClassFileParser.{ConstValueIndex, Annotation} import tools.nsc.util.{ ClassPath } import tools.util.PathResolver import ClassPath.DefaultJavaContext import tools.nsc.io.{PlainFile, AbstractFile} -import scala.reflect.generic.ByteCodecs /**The main object used to execute scalap on the command-line. * @@ -104,25 +102,10 @@ object Main { 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 => "" - } - } - 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) + ScalaSigParser.parse(classFile) match { + case Some(scalaSig) => parseScalaSignature(scalaSig, isPackageObject) + case None => "" } } diff --git a/src/scalap/scala/tools/scalap/scalax/rules/scalasig/ScalaSig.scala b/src/scalap/scala/tools/scalap/scalax/rules/scalasig/ScalaSig.scala index d2e50deae3..4614d27727 100644 --- a/src/scalap/scala/tools/scalap/scalax/rules/scalasig/ScalaSig.scala +++ b/src/scalap/scala/tools/scalap/scalax/rules/scalasig/ScalaSig.scala @@ -11,27 +11,45 @@ package scalax package rules package scalasig +import ClassFileParser.{ ConstValueIndex, Annotation } +import scala.reflect.generic.ByteCodecs + object ScalaSigParser { + import Main.{ SCALA_SIG, SCALA_SIG_ANNOTATION, BYTES_VALUE } - def getScalaSig(clazz : Class[_]) : Option[ByteCode] = { - val byteCode = ByteCode.forClass(clazz) - val classFile = ClassFileParser.parse(byteCode) + def scalaSigFromAnnotation(classFile: ClassFile): Option[ScalaSig] = { + import classFile._ + + classFile.annotation(SCALA_SIG_ANNOTATION) map { + case 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) - /* - println("ClassFile version: " + classFile.majorVersion + "." + classFile.minorVersion) - println("Class: " + classFile.className) - println("Superclass: " + classFile.superClass) - println("Interfaces: " + classFile.interfaces.mkString(", ")) - println("Constant pool:") - val constantPool = classFile.header.constants - for (i <- 1 to constantPool.size) println(i + "\t" + constantPool(i)) - */ - - classFile.attribute("ScalaSig").map(_.byteCode) + ScalaSigAttributeParsers.parse(ByteCode(bytes.take(length))) + } } - def parse(clazz : Class[_]) : Option[ScalaSig] = { - getScalaSig(clazz).map(ScalaSigAttributeParsers.parse) + def scalaSigFromAttribute(classFile: ClassFile) : Option[ScalaSig] = + classFile.attribute(SCALA_SIG).map(_.byteCode).map(ScalaSigAttributeParsers.parse) + + def parse(classFile: ClassFile): Option[ScalaSig] = { + val scalaSig = scalaSigFromAttribute(classFile) + + scalaSig match { + // No entries in ScalaSig attribute implies that the signature is stored in the annotation + case Some(ScalaSig(_, _, entries)) if entries.length == 0 => + scalaSigFromAnnotation(classFile) + case x => x + } + } + + def parse(clazz : Class[_]): Option[ScalaSig] = { + val byteCode = ByteCode.forClass(clazz) + val classFile = ClassFileParser.parse(byteCode) + + parse(classFile) } } -- cgit v1.2.3