Как получить ScalaSig для объекта-компаньона? - PullRequest
2 голосов
/ 27 декабря 2010

В библиотеке scalap есть функция для анализа специфичной для Scala информации из файлов классов. Для обычного класса я могу получить такую ​​информацию:

scala> ScalaSigParser.parse(classOf[BasicCase])
res46: Option[scala.tools.scalap.scalax.rules.scalasig.ScalaSig] = 
Some(ScalaSig version 5.0
0: ClassSymbol(BasicCase, owner=<empty>, flags=40000040, info=5 ,None)
1: BasicCase
2: <empty>
3: <empty>
4: NoSymbol
5: ClassInfoType(ClassSymbol(BasicCase, owner=<empty>, flags=40000040, info=5 ,None),List(TypeRefType(ThisType(java.lang),java.lang.Object,List()), TypeRefType(ThisType(scala),scala.ScalaObject,List()), TypeRefType(ThisType(scala),scala.Product,List())))
6: TypeRefType(ThisType(java.lang),java.lang.Object,List())
7: ThisType(java.lang)
8: java.lang
9: lang
10: java
11: java
12: java.lang.Object
13: Object
14: TypeRefType(ThisType(scala),scala.ScalaObject,List())
15: ThisType(scala)
16: scala
17: scala
18: scala.ScalaObject
19: ScalaObject
20: TypeRefType(ThisType(scala),scala.Pr...
scala> 

... и оттуда получают всякие вкусности по поводу внутренних органов. Но для объекта-компаньона:

scala> ScalaSigParser.parse(classOf[BasicCase$])
res47: Option[scala.tools.scalap.scalax.rules.scalasig.ScalaSig] = None

... Я ничего не понимаю. Однако Scalap будет работать с классом объекта-компаньона:

scalap -cp . BasicCase$
package BasicCase$;
final class BasicCase$ extends scala.runtime.AbstractFunction3 with java.io.Serializable with scala.ScalaObject {
  def this(): scala.Unit;
  def apply(scala.Any, scala.Any, scala.Any): scala.Any;
  def readResolve(): scala.Any;
  def apply(scala.Int, java.lang.String, scala.Option): BasicCase;
  def unapply(BasicCase): scala.Option;
}
object BasicCase$ {
  final val MODULE$: BasicCase$;
}

Так что должен быть способ, я просто не смог его найти. У кого-нибудь есть идеи?

РЕДАКТИРОВАТЬ: Я нашел это, но все еще нужно больше:

scala> bcSig.topLevelObjects
res59: List[scala.tools.scalap.scalax.rules.scalasig.ObjectSymbol] = List(ObjectSymbol(BasicCase, owner=<empty>, flags=200402, info=124 ))

scala> bcSig.topLevelObjects.head
res60: scala.tools.scalap.scalax.rules.scalasig.ObjectSymbol = ObjectSymbol(BasicCase, owner=<empty>, flags=200402, info=124 )

К сожалению, метод children, похоже, не дает мне методов:

scala> res60.children                          
res70: Seq[scala.tools.scalap.scalax.rules.scalasig.Symbol] = List()

В отличие от обычного класса:

scala> bcSym.children
res71: Seq[scala.tools.scalap.scalax.rules.scalasig.Symbol] = List(MethodSymbol(id, owner=0, flags=29400200, info=25 ,None), MethodSymbol(id , owner=0, flags=21080004, info=26 ,None), MethodSymbol(name, owner=0, flags=29400200, info=33 ,None), MethodSymbol(name , owner=0, flags=21080004, info=34 ,None), MethodSymbol(data, owner=0, flags=29400200, info=45 ,None), MethodSymbol(data , owner=0, flags=21080004, info=46 ,None), MethodSymbol(<init>, owner=0, flags=200, info=53 ,None), MethodSymbol(copy, owner=0, flags=200200, info=61 ,None), MethodSymbol(copy$default$1, owner=0, flags=2200200, info=67 ,None), MethodSymbol(copy$default$2, owner=0, flags=2200200, info=80 ,None), MethodSymbol(copy$default$3, owner=0, flags=2200200, info=84 ,None), MethodSymbol(hashCode, owner=0, flags=40000220, i...

1 Ответ

1 голос
/ 27 декабря 2010

Я думаю, что можно получить методы компаньона, используя infoType, я использовал List в качестве образца и res17 эквивалентно вашему res60:

    scala> res17
    res23: scala.tools.scalap.scalax.rules.scalasig.ObjectSymbol = 
ObjectSymbol(List, owner=scala.collection.immutable, flags=402, info=273 )

    scala> res17.infoType.asInstanceOf[TypeRefType].symbol.children
    res22: Seq[scala.tools.scalap.scalax.rules.scalasig.Symbol] = List(
    MethodSymbol(<init>, owner=274, flags=200, info=280 ,None), 
    MethodSymbol(canBuildFrom, owner=274, flags=201, info=283 ,None), 
    MethodSymbol(newBuilder, owner=274, flags=200, info=294 ,None), 
    MethodSymbol(empty, owner=274, flags=220, info=306 ,None), 
    MethodSymbol(apply, owner=274, flags=220, info=312 ,None), 
    MethodSymbol(range, owner=274, flags=200, info=324 ,None), 
    MethodSymbol(make, owner=274, flags=200, info=336 ,None), 
    MethodSymbol(flatten, owner=274, flags=200, info=348 ,None), 
    MethodSymbol(unzip, owner=274, flags=200, info=361 ,None), 
    MethodSymbol(unzip, owner=274, flags=200, info=377 ,None), 
    MethodSymbol(lefts, owner=274, flags=200, info=394 ,None), 
    MethodSymbol(rights, owner=274, flags=200, info=412 ,None)...

Обратите внимание на методы lefts и rights, которых нет в классе List.

...