def fromClassfile()

in scalasig/scalasig/src/main/scala/scala/meta/internal/scalasig/ScalasigCodec.scala [17:241]


  def fromClassfile(classfile: Classfile): Option[Scalasig] = {
    classfile.payload match {
      case ScalaPayload(bytes) =>
        val reader = new ScalasigReader(bytes)
        import reader._

        val majorVersion = readVarint()
        assert(majorVersion == MajorVersion)
        val minorVersion = readVarint()
        assert(minorVersion == MinorVersion)

        val numEntries = readVarint()
        val entriesStart = offset
        val entryStarts = new Array[Int](numEntries)
        var entryIndex = 0
        while (entryIndex < numEntries) {
          entryStarts(entryIndex) = offset
          val entryTag = readByte()
          val entryLen = readVarint()
          offset += entryLen
          entryIndex += 1
        }

        val entries = new Array[Entry](numEntries)
        offset = entriesStart
        entryIndex = 0
        while (entryIndex < numEntries) {
          val entryTag = readByte()
          val entryLen = readVarint()
          val entryEnd = offset + entryLen
          def readRef(): Ref = {
            readVarint()
          }
          def readRefs(atEnd: Boolean = true): List[Ref] = {
            val buf = List.newBuilder[Ref]
            if (atEnd) {
              while (offset < entryEnd) {
                buf += readRef()
              }
            } else {
              var times = readVarint()
              while (times > 0) {
                buf += readRef()
                times -= 1
              }
            }
            buf.result
          }
          def readRefss(atEnd: Boolean = true): List[List[Ref]] = {
            val buf = List.newBuilder[List[Ref]]
            if (atEnd) {
              while (offset < entryEnd) {
                buf += readRefs(atEnd = false)
              }
            } else {
              var times = readVarint()
              while (times > 0) {
                buf += readRefs(atEnd = false)
              }
            }
            buf.result
          }
          def readEmbeddedSymbol(): Symbol = {
            val name = readRef()
            val owner = readRef()
            val flags = readVarlong()
            val (within, info) = {
              val ref = readRef()
              val tag = atOffset(entryStarts(ref))(readByte())
              if (NONEsym <= tag && tag <= EXTMODCLASSref) (Some(ref), readRef())
              else (None, ref)
            }
            entryTag match {
              case TYPEsym =>
                TypeSymbol(name, owner, flags, within, info)
              case ALIASsym =>
                AliasSymbol(name, owner, flags, within, info)
              case CLASSsym =>
                val thisType = if (offset < entryEnd) Some(readRef()) else None
                ClassSymbol(name, owner, flags, within, info, thisType)
              case MODULEsym =>
                ModuleSymbol(name, owner, flags, within, info)
              case VALsym =>
                val alias = if (offset < entryEnd) Some(readRef()) else None
                ValSymbol(name, owner, flags, within, info, alias)
            }
          }
          def readExternalSymbol(): Symbol = {
            val name = readRef()
            val owner = if (offset < entryEnd) Some(readRef()) else None
            entryTag match {
              case EXTref => ExtRef(name, owner)
              case EXTMODCLASSref => ExtModClassRef(name, owner)
            }
          }
          def readNumber(): Long = {
            offset = entryStarts(entryIndex) + 1
            reader.readNumber()
          }
          def readAnnotArgs(): List[AnnotArg] = {
            val buf = List.newBuilder[AnnotArg]
            while (offset < entryEnd) {
              val ref = readRef()
              val tag = atOffset(entryStarts(ref))(readByte())
              if (TERMname <= tag && tag <= TYPEname) {
                buf += JavaAnnotArg(ref, readRef())
              } else {
                buf += ScalaAnnotArg(ref)
              }
            }
            buf.result
          }
          def readImportSelectors(): List[ImportSelector] = {
            val buf = List.newBuilder[ImportSelector]
            while (offset < entryEnd) {
              buf += ImportSelector(readRef(), readRef())
            }
            buf.result
          }
          def readTree(): Tree = {
            val treeTag = readByte()
            treeTag match {
              case EMPTYtree => EmptyTree
              case PACKAGEDEFtree => PackageDefTree(readRef(), readRef(), readRef(), readRefs())
              case CLASSDEFtree => ClassDefTree(readRef(), readRef(), readRef(), readRef(), readRefs(atEnd = false), readRef())
              case MODULEDEFtree => ModuleDefTree(readRef(), readRef(), readRef(), readRef(), readRef())
              case VALDEFtree => ValDefTree(readRef(), readRef(), readRef(), readRef(), readRef(), readRef())
              case DEFDEFtree => DefDefTree(readRef(), readRef(), readRef(), readRef(), readRefs(atEnd = false), readRefss(atEnd = false), readRef(), readRef())
              case TYPEDEFtree => TypeDefTree(readRef(), readRef(), readRef(), readRef(), readRefs(atEnd = false), readRef())
              case LABELDEFtree => LabelDefTree(readRef(), readRef(), readRef(), readRefs(atEnd = false), readRef())
              case IMPORTtree => ImportTree(readRef(), readRef(), readRef(), readImportSelectors())
              case TEMPLATEtree => TemplateTree(readRef(), readRef(), readRefs(atEnd = false), readRef(), readRefs())
              case BLOCKtree => BlockTree(readRef(), readRefs())
              case CASEtree => CaseTree(readRef(), readRef(), readRef(), readRef())
              case ALTERNATIVEtree => AlternativeTree(readRef(), readRefs())
              case STARtree => StarTree(readRef(), readRef())
              case BINDtree => BindTree(readRef(), readRef(), readRef(), readRef())
              case UNAPPLYtree => UnapplyTree(readRef(), readRef(), readRefs())
              case ARRAYVALUEtree => ArrayValueTree(readRef(), readRef(), readRefs())
              case FUNCTIONtree => FunctionTree(readRef(), readRef(), readRefs(atEnd = false), readRef())
              case ASSIGNtree => AssignTree(readRef(), readRef(), readRef())
              case IFtree => IfTree(readRef(), readRef(), readRef(), readRef())
              case MATCHtree => MatchTree(readRef(), readRef(), readRefs())
              case RETURNtree => ReturnTree(readRef(), readRef(), readRef())
              case TRYtree => TryTree(readRef(), readRef(), readRefs(atEnd = false), readRef())
              case THROWtree => ThrowTree(readRef(), readRef())
              case NEWtree => NewTree(readRef(), readRef())
              case TYPEDtree => TypedTree(readRef(), readRef(), readRef())
              case TYPEAPPLYtree => TypeApplyTree(readRef(), readRef(), readRefs())
              case APPLYtree => ApplyTree(readRef(), readRef(), readRefs())
              case APPLYDYNAMICtree => ApplyDynamicTree(readRef(), readRef(), readRef(), readRefs())
              case SUPERtree => SuperTree(readRef(), readRef(), readRef(), readRef())
              case THIStree => ThisTree(readRef(), readRef(), readRef())
              case SELECTtree => SelectTree(readRef(), readRef(), readRef(), readRef())
              case IDENTtree => IdentTree(readRef(), readRef(), readRef())
              case LITERALtree => LiteralTree(readRef(), readRef())
              case TYPEtree => TypeTree(readRef())
              case ANNOTATEDtree => AnnotatedTree(readRef(), readRef(), readRef())
              case SINGLETONTYPEtree => SingletonTypeTree(readRef(), readRef())
              case SELECTFROMTYPEtree => SelectFromTypeTree(readRef(), readRef(), readRef())
              case COMPOUNDTYPEtree => CompoundTypeTree(readRef(), readRef())
              case APPLIEDTYPEtree => AppliedTypeTree(readRef(), readRef(), readRefs())
              case TYPEBOUNDStree => TypeBoundsTree(readRef(), readRef(), readRef())
              case EXISTENTIALTYPEtree => ExistentialTypeTree(readRef(), readRef(), readRefs())
            }
          }
          def readModifierFlags(): Long = {
            val hi = readVarint()
            val lo = readVarint()
            (hi.toLong << 32) + lo
          }
          val entry = entryTag match {
            case TERMname => TermName(readString(entryLen))
            case TYPEname => TypeName(readString(entryLen))
            case NONEsym => NoSymbol
            case TYPEsym => readEmbeddedSymbol()
            case ALIASsym => readEmbeddedSymbol()
            case CLASSsym => readEmbeddedSymbol()
            case MODULEsym => readEmbeddedSymbol()
            case VALsym => readEmbeddedSymbol()
            case EXTref => readExternalSymbol()
            case EXTMODCLASSref => readExternalSymbol()
            case CHILDREN => Children(readRef(), readRefs())
            case NOtpe => NoType
            case NOPREFIXtpe => NoPrefix
            case THIStpe => ThisType(readRef())
            case SINGLEtpe => SingleType(readRef(), readRef())
            case CONSTANTtpe => ConstantType(readRef())
            case TYPEREFtpe => TypeRef(readRef(), readRef(), readRefs())
            case TYPEBOUNDStpe => TypeBounds(readRef(), readRef())
            case REFINEDtpe => RefinedType(readRef(), readRefs())
            case CLASSINFOtpe => ClassInfoType(readRef(), readRefs())
            case METHODtpe => MethodType(readRef(), readRefs())
            case POLYtpe => PolyType(readRef(), readRefs())
            case SUPERtpe => SuperType(readRef(), readRef())
            case ANNOTATEDtpe => AnnotatedType(readRef(), readRefs())
            case EXISTENTIALtpe => ExistentialType(readRef(), readRefs())
            case LITERALunit => UnitLit
            case LITERALboolean => BooleanLit(readNumber() != 0L)
            case LITERALbyte => ByteLit(readNumber().toByte)
            case LITERALshort => ShortLit(readNumber().toShort)
            case LITERALchar => CharLit(readNumber().toChar)
            case LITERALint => IntLit(readNumber().toInt)
            case LITERALlong => LongLit(readNumber().toLong)
            case LITERALfloat => FloatLit(intBitsToFloat(readNumber().toInt))
            case LITERALdouble => DoubleLit(longBitsToDouble(readNumber()))
            case LITERALstring => StringLit(readRef())
            case LITERALnull => NullLit
            case LITERALclass => ClassLit(readRef())
            case LITERALenum => EnumLit(readRef())
            case SYMANNOT => SymAnnot(readRef(), readRef(), readAnnotArgs())
            case ANNOTINFO => AnnotInfo(readRef(), readAnnotArgs())
            case ANNOTARGARRAY => AnnotArgArray(readRefs())
            case TREE => readTree()
            case MODIFIERS => Modifiers(readModifierFlags(), readRef())
          }
          entries(entryIndex) = entry
          entryIndex += 1
        }

        Some(Scalasig(classfile.name, classfile.source, entries))
      case _ =>
        None
    }
  }