diff options
Diffstat (limited to 'src/compiler/scalax/rules/scalasig/ScalaSig.scala')
-rw-r--r-- | src/compiler/scalax/rules/scalasig/ScalaSig.scala | 269 |
1 files changed, 269 insertions, 0 deletions
diff --git a/src/compiler/scalax/rules/scalasig/ScalaSig.scala b/src/compiler/scalax/rules/scalasig/ScalaSig.scala new file mode 100644 index 0000000000..a65298f0be --- /dev/null +++ b/src/compiler/scalax/rules/scalasig/ScalaSig.scala @@ -0,0 +1,269 @@ +package scalax.rules.scalasig + +object ScalaSigParser { + + def getScalaSig(clazz : Class[_]) : Option[ByteCode] = { + val byteCode = ByteCode.forClass(clazz) + val classFile = ClassFileParser.parse(byteCode) + + /* + 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) + } + + def parse(clazz : Class[_]) : Option[ScalaSig] = { + getScalaSig(clazz).map(ScalaSigAttributeParsers.parse) + } +} + +object ScalaSigAttributeParsers extends ByteCodeReader { + def parse(byteCode : ByteCode) = expect(scalaSig)(byteCode) + + val nat = apply { + def natN(in : ByteCode, x : Int) : Result[ByteCode, Int, Nothing] = in.nextByte match { + case Success(out, b) => { + val y = (x << 7) + (b & 0x7f) + if ((b & 0x80) == 0) Success(out, y) else natN(out, y) + } + case _ => Failure + } + in => natN(in, 0) + } + + val rawBytes = nat >> bytes + val entry = nat ~ rawBytes + val symtab = nat >> entry.times + val scalaSig = nat ~ nat ~ symtab ^~~^ ScalaSig + + val utf8 = read(_ toUTF8String) + val longValue = read(_ toLong) +} + +case class ScalaSig(majorVersion : Int, minorVersion : Int, table : Seq[Int ~ ByteCode]) extends DefaultMemoisable { + + case class Entry(index : Int, entryType : Int, byteCode : ByteCode) extends DefaultMemoisable { + def scalaSig = ScalaSig.this + + def setByteCode(byteCode : ByteCode) = Entry(index, entryType, byteCode) + } + + def hasEntry(index : Int) = table isDefinedAt index + + def getEntry(index : Int) = { + val entryType ~ byteCode = table(index) + Entry(index, entryType, byteCode) + } + + def parseEntry(index : Int) = applyRule(ScalaSigParsers.parseEntry(ScalaSigEntryParsers.entry)(index)) + + implicit def applyRule[A](parser : ScalaSigParsers.Parser[A]) = ScalaSigParsers.expect(parser)(this) + + override def toString = "ScalaSig version " + majorVersion + "." + minorVersion + { + for (i <- 0 until table.size) yield i + ":\t" + parseEntry(i) // + "\n\t" + getEntry(i) + }.mkString("\n", "\n", "") + + lazy val symbols : Seq[Symbol] = ScalaSigParsers.symbols + + lazy val topLevelClasses : List[ClassSymbol] = ScalaSigParsers.topLevelClasses + lazy val topLevelObjects : List[ObjectSymbol] = ScalaSigParsers.topLevelObjects +} + +object ScalaSigParsers extends RulesWithState with MemoisableRules { + type S = ScalaSig + type Parser[A] = Rule[A, String] + + val symTab = read(_.table) + val size = symTab ^^ (_.size) + + def entry(index : Int) = memo(("entry", index)) { + cond(_ hasEntry index) -~ read(_ getEntry index) >-> { entry => Success(entry, entry.entryType) } + } + + def parseEntry[A](parser : ScalaSigEntryParsers.EntryParser[A])(index : Int) : Parser[A] = + entry(index) -~ parser >> { a => entry => Success(entry.scalaSig, a) } + + def allEntries[A](f : ScalaSigEntryParsers.EntryParser[A]) = size >> { n => anyOf((0 until n) map parseEntry(f)) } + + lazy val entries = allEntries(ScalaSigEntryParsers.entry) as "entries" + lazy val symbols = allEntries(ScalaSigEntryParsers.symbol) as "symbols" + lazy val methods = allEntries(ScalaSigEntryParsers.methodSymbol) as "methods" + lazy val attributes = allEntries(ScalaSigEntryParsers.attributeInfo) as "attributes" + + lazy val topLevelClasses = allEntries(ScalaSigEntryParsers.topLevelClass) + lazy val topLevelObjects = allEntries(ScalaSigEntryParsers.topLevelObject) +} + +object ScalaSigEntryParsers extends RulesWithState with MemoisableRules { + import ScalaSigAttributeParsers.{nat, utf8, longValue} + + type S = ScalaSig#Entry + type EntryParser[A] = Rule[A, String] + + implicit def byteCodeEntryParser[A](rule : ScalaSigAttributeParsers.Parser[A]) : EntryParser[A] = apply { entry => + rule(entry.byteCode) mapOut (entry setByteCode _) + } + + def toEntry[A](index : Int) = apply { sigEntry => ScalaSigParsers.entry(index)(sigEntry.scalaSig) } + + def parseEntry[A](parser : EntryParser[A])(index : Int) = (toEntry(index) -~ parser) + + implicit def entryType(code : Int) = key filter (_ == code) + + val index = read(_.index) + val key = read(_.entryType) + + lazy val entry : EntryParser[Any] = symbol | typeEntry | literal | name | attributeInfo | annotInfo | children | get + + val ref = byteCodeEntryParser(nat) + + val termName = 1 -~ utf8 + val typeName = 2 -~ utf8 + + val name = termName | typeName as "name" + + def refTo[A](rule : EntryParser[A]) : EntryParser[A] = ref >>& parseEntry(rule) + + lazy val nameRef = refTo(name) + lazy val symbolRef = refTo(symbol) + lazy val typeRef = refTo(typeEntry) + lazy val constantRef = refTo(literal) + + val symbolInfo = nameRef ~ symbolRef ~ nat ~ (symbolRef?) ~ ref ~ get ^~~~~~^ SymbolInfo + + def symbolEntry(key : Int) = (key -~ none | (key + 64) -~ nat) -~ symbolInfo + + val noSymbol = 3 -^ NoSymbol + val typeSymbol = symbolEntry(4) ^^ TypeSymbol as "typeSymbol" + val aliasSymbol = symbolEntry(5) ^^ AliasSymbol as "alias" + val classSymbol = symbolEntry(6) ~ (ref?) ^~^ ClassSymbol as "class" + val objectSymbol = symbolEntry(7) ^^ ObjectSymbol as "object" + val methodSymbol = symbolEntry(8) ~ (ref?) ^~^ MethodSymbol as "method" + val extRef = 9 -~ nameRef ~ (symbolRef?) ~ get ^~~^ ExternalSymbol as "extRef" + val extModClassRef = 10 -~ nameRef ~ (symbolRef?) ~ get ^~~^ ExternalSymbol as "extModClassRef" + + lazy val symbol : EntryParser[Symbol] = oneOf( + noSymbol, + typeSymbol, + aliasSymbol, + classSymbol, + objectSymbol, + methodSymbol, + extRef, + extModClassRef) as "symbol" + + val classSymRef = refTo(classSymbol) + val attribTreeRef = ref + val typeLevel = nat + val typeIndex = nat + + lazy val typeEntry : EntryParser[Type] = oneOf( + 11 -^ NoType, + 12 -^ NoPrefixType, + 13 -~ symbolRef ^^ ThisType, + 14 -~ typeRef ~ symbolRef ^~^ SingleType, + 15 -~ constantRef ^^ ConstantType, + 16 -~ typeRef ~ symbolRef ~ (typeRef*) ^~~^ TypeRefType, + 17 -~ typeRef ~ typeRef ^~^ TypeBoundsType, + 18 -~ classSymRef ~ (typeRef*) ^~^ RefinedType, + 19 -~ symbolRef ~ (typeRef*) ^~^ ClassInfoType, + 20 -~ typeRef ~ (typeRef*) ^~^ MethodType, + 21 -~ typeRef ~ (refTo(typeSymbol)*) ^~^ PolyType, + 22 -~ typeRef ~ (typeRef*) ^~^ ImplicitMethodType, + 42 -~ typeRef ~ (attribTreeRef*) ^~^ AnnotatedType, + 51 -~ typeRef ~ symbolRef ~ (attribTreeRef*) ^~~^ AnnotatedWithSelfType, + 47 -~ typeLevel ~ typeIndex ^~^ DeBruijnIndexType, + 48 -~ typeRef ~ (symbolRef*) ^~^ ExistentialType) as "type" + + lazy val literal = oneOf( + 24 -^ (), + 25 -~ longValue ^^ (_ != 0), + 26 -~ longValue ^^ (_.asInstanceOf[Byte]), + 27 -~ longValue ^^ (_.asInstanceOf[Short]), + 28 -~ longValue ^^ (_.asInstanceOf[Char]), + 29 -~ longValue ^^ (_.asInstanceOf[Int]), + 30 -~ longValue ^^ (_.asInstanceOf[Long]), + 31 -~ longValue ^^ (l => java.lang.Float.intBitsToFloat(l.asInstanceOf[Int])), + 32 -~ longValue ^^ (java.lang.Double.longBitsToDouble), + 33 -~ nameRef, + 34 -^ null, + 35 -~ typeRef) + + lazy val attributeInfo = 40 -~ symbolRef ~ typeRef ~ (constantRef?) ~ (nameRef ~ constantRef *) ^~~~^ AttributeInfo // sym_Ref info_Ref {constant_Ref} {nameRef constantRef} + lazy val children = 41 -~ (nat*) ^^ Children //sym_Ref {sym_Ref} + lazy val annotInfo = 43 -~ (nat*) ^^ AnnotInfo // attarg_Ref {constant_Ref attarg_Ref} + + lazy val topLevelClass = classSymbol filter isTopLevelClass + lazy val topLevelObject = objectSymbol filter isTopLevel + + def isTopLevel(symbol : Symbol) = symbol.parent match { + case Some(ext : ExternalSymbol) => true + case _ => false + } + def isTopLevelClass (symbol : Symbol) = !symbol.isModule && isTopLevel(symbol) +} + + case class AttributeInfo(symbol : Symbol, typeRef : Type, value : Option[Any], values : Seq[String ~ Any]) // sym_Ref info_Ref {constant_Ref} {nameRef constantRef} + case class Children(symbolRefs : Seq[Int]) //sym_Ref {sym_Ref} + + case class AnnotInfo(refs : Seq[Int]) // attarg_Ref {constant_Ref attarg_Ref} + + /* | 49 TREE len_Nat 1 EMPTYtree + * | 49 TREE len_Nat 2 PACKAGEtree type_Ref sym_Ref mods_Ref name_Ref {tree_Ref} + * | 49 TREE len_Nat 3 CLASStree type_Ref sym_Ref mods_Ref name_Ref tree_Ref {tree_Ref} + * | 49 TREE len_Nat 4 MODULEtree type_Ref sym_Ref mods_Ref name_Ref tree_Ref + * | 49 TREE len_Nat 5 VALDEFtree type_Ref sym_Ref mods_Ref name_Ref tree_Ref tree_Ref + * | 49 TREE len_Nat 6 DEFDEFtree type_Ref sym_Ref mods_Ref name_Ref numtparams_Nat {tree_Ref} numparamss_Nat {numparams_Nat {tree_Ref}} tree_Ref tree_Ref + * | 49 TREE len_Nat 7 TYPEDEFtree type_Ref sym_Ref mods_Ref name_Ref tree_Ref {tree_Ref} + * | 49 TREE len_Nat 8 LABELtree type_Ref sym_Ref tree_Ref {tree_Ref} + * | 49 TREE len_Nat 9 IMPORTtree type_Ref sym_Ref tree_Ref {name_Ref name_Ref} + * | 49 TREE len_Nat 10 ANNOTATIONtree type_Ref sym_Ref tree_Ref {tree_Ref} + * | 49 TREE len_Nat 11 DOCDEFtree type_Ref sym_Ref string_Ref tree_Ref + * | 49 TREE len_Nat 12 TEMPLATEtree type_Ref sym_Ref numparents_Nat {tree_Ref} tree_Ref {tree_Ref} + * | 49 TREE len_Nat 13 BLOCKtree type_Ref tree_Ref {tree_Ref} + * | 49 TREE len_Nat 14 CASEtree type_Ref tree_Ref tree_Ref tree_Ref + * | 49 TREE len_Nat 15 SEQUENCEtree type_Ref {tree_Ref} + * | 49 TREE len_Nat 16 ALTERNATIVEtree type_Ref {tree_Ref} + * | 49 TREE len_Nat 17 STARtree type_Ref {tree_Ref} + * | 49 TREE len_Nat 18 BINDtree type_Ref sym_Ref name_Ref tree_Ref + * | 49 TREE len_Nat 19 UNAPPLYtree type_Ref tree_Ref {tree_Ref} + * | 49 TREE len_Nat 20 ARRAYVALUEtree type_Ref tree_Ref {tree_Ref} + * | 49 TREE len_Nat 21 FUNCTIONtree type_Ref sym_Ref tree_Ref {tree_Ref} + * | 49 TREE len_Nat 22 ASSIGNtree type_Ref tree_Ref tree_Ref + * | 49 TREE len_Nat 23 IFtree type_Ref tree_Ref tree_Ref tree_Ref + * | 49 TREE len_Nat 24 MATCHtree type_Ref tree_Ref {tree_Ref} + * | 49 TREE len_Nat 25 RETURNtree type_Ref sym_Ref tree_Ref + * | 49 TREE len_Nat 26 TREtree type_Ref tree_Ref tree_Ref {tree_Ref} + * | 49 TREE len_Nat 27 THROWtree type_Ref tree_Ref + * | 49 TREE len_Nat 28 NEWtree type_Ref tree_Ref + * | 49 TREE len_Nat 29 TYPEDtree type_Ref tree_Ref tree_Ref + * | 49 TREE len_Nat 30 TYPEAPPLYtree type_Ref tree_Ref {tree_Ref} + * | 49 TREE len_Nat 31 APPLYtree type_Ref tree_Ref {tree_Ref} + * | 49 TREE len_Nat 32 APPLYDYNAMICtree type_Ref sym_Ref tree_Ref {tree_Ref} + * | 49 TREE len_Nat 33 SUPERtree type_Ref sym_Ref tree_Ref name_Ref + * | 49 TREE len_Nat 34 THIStree type_Ref sym_Ref name_Ref + * | 49 TREE len_Nat 35 SELECTtree type_Ref sym_Ref tree_Ref name_Ref + * | 49 TREE len_Nat 36 IDENTtree type_Ref sym_Ref name_Ref + * | 49 TREE len_Nat 37 LITERALtree type_Ref constant_Ref + * | 49 TREE len_Nat 38 TYPEtree type_Ref + * | 49 TREE len_Nat 39 ANNOTATEDtree type_Ref tree_Ref tree_Ref + * | 49 TREE len_Nat 40 SINGLETONTYPEtree type_Ref tree_Ref + * | 49 TREE len_Nat 41 SELECTFROMTYPEtree type_Ref tree_Ref name_Ref + * | 49 TREE len_Nat 42 COMPOUNDTYPEtree type_Ref tree_Ref + * | 49 TREE len_Nat 43 APPLIEDTYPEtree type_Ref tree_Ref {tree_Ref} + * | 49 TREE len_Nat 44 TYPEBOUNDStree type_Ref tree_Ref tree_Ref + * | 49 TREE len_Nat 45 EXISTENTIALTYPEtree type_Ref tree_Ref {tree_Ref} + * | 50 MODIFIERS len_Nat flags_Long privateWithin_Ref {Annotation_Ref} + + * Attarg = Refltree | Constant + * + * len is remaining length after `len'. + */ + |