summaryrefslogtreecommitdiff
path: root/src/scalap
diff options
context:
space:
mode:
authorMichał Pociecha <michal.pociecha@gmail.com>2015-05-02 15:56:42 +0200
committerMichał Pociecha <michal.pociecha@gmail.com>2015-05-03 10:23:39 +0200
commit6097fe5d8434f8e65595b74aa01cd6bf610c8f48 (patch)
treeb1a8c7e93fb625eed2fa2db4c1d4ae5725b9e3c7 /src/scalap
parent454a1dcf0c3568ea99f669529b4819782b8b2f00 (diff)
downloadscala-6097fe5d8434f8e65595b74aa01cd6bf610c8f48.tar.gz
scala-6097fe5d8434f8e65595b74aa01cd6bf610c8f48.tar.bz2
scala-6097fe5d8434f8e65595b74aa01cd6bf610c8f48.zip
SI-8679 Add support for ScalaLongSignature attribute in scalap
scalap didn't support really big class files. It was returning an empty String for such files. The reason was that there were only ScalaSignatures taken into account. This commit adds support for ScalaLongSignature. We try to get such an attribute when we didn't find ScalaSignature. Also there's added an additional case to the logic retrieving bytes for a signature. Since ScalaLongSignature can contain many parts, we have to merge their byte arrays. Changes are tested by a new partest-based test. These two files are really big, but it was required (t8679.scala is a reduced version of BigScalaClass - an example attached to JIRA). There are also added TODOs with a JIRA ticket: We have three places, where we process Scala signatures. In the future it would be better to reuse some common logic, if it's possible.
Diffstat (limited to 'src/scalap')
-rw-r--r--src/scalap/scala/tools/scalap/Main.scala1
-rw-r--r--src/scalap/scala/tools/scalap/scalax/rules/scalasig/ScalaSig.scala22
2 files changed, 18 insertions, 5 deletions
diff --git a/src/scalap/scala/tools/scalap/Main.scala b/src/scalap/scala/tools/scalap/Main.scala
index 7c554d196c..3d2bfd7251 100644
--- a/src/scalap/scala/tools/scalap/Main.scala
+++ b/src/scalap/scala/tools/scalap/Main.scala
@@ -28,6 +28,7 @@ import scalax.rules.scalasig._
class Main {
val SCALA_SIG = "ScalaSig"
val SCALA_SIG_ANNOTATION = "Lscala/reflect/ScalaSignature;"
+ val SCALA_LONG_SIG_ANNOTATION = "Lscala/reflect/ScalaLongSignature;"
val BYTES_VALUE = "bytes"
val versionMsg = "Scala classfile decoder %s -- %s\n".format(Properties.versionString, Properties.copyrightString)
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 e3076322dd..c36fdd02cd 100644
--- a/src/scalap/scala/tools/scalap/scalax/rules/scalasig/ScalaSig.scala
+++ b/src/scalap/scala/tools/scalap/scalax/rules/scalasig/ScalaSig.scala
@@ -14,20 +14,32 @@ package scalasig
import scala.language.postfixOps
import scala.language.implicitConversions
-import ClassFileParser.{ ConstValueIndex, Annotation }
+import ClassFileParser._
import scala.reflect.internal.pickling.ByteCodecs
object ScalaSigParser {
- import Main.{ SCALA_SIG, SCALA_SIG_ANNOTATION, BYTES_VALUE }
+ import Main.{ BYTES_VALUE, SCALA_LONG_SIG_ANNOTATION, SCALA_SIG, SCALA_SIG_ANNOTATION }
+ // TODO SI-9296 duplicated code, refactor
def scalaSigFromAnnotation(classFile: ClassFile): Option[ScalaSig] = {
import classFile._
- classFile.annotation(SCALA_SIG_ANNOTATION) map {
+ def getBytes(bytesElem: AnnotationElement): Array[Byte] = bytesElem.elementValue match {
+ case ConstValueIndex(index) => bytesForIndex(index)
+ case ArrayValue(signatureParts) => mergedLongSignatureBytes(signatureParts)
+ }
+
+ def mergedLongSignatureBytes(signatureParts: Seq[ElementValue]): Array[Byte] = signatureParts.flatMap {
+ case ConstValueIndex(index) => bytesForIndex(index)
+ }(collection.breakOut)
+
+ def bytesForIndex(index: Int) = constantWrapped(index).asInstanceOf[StringBytesPair].bytes
+
+ classFile.annotation(SCALA_SIG_ANNOTATION)
+ .orElse(classFile.annotation(SCALA_LONG_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 bytes = getBytes(bytesElem)
val length = ByteCodecs.decode(bytes)
ScalaSigAttributeParsers.parse(ByteCode(bytes.take(length)))