def pruneAdapt()

in scrooge-adaptive/src/main/scala/com/twitter/scrooge/adapt/AdaptASMPruner.scala [45:105]


  def pruneAdapt(templateFqdn: String, useMap: Map[String, Boolean]): Array[Byte] = {
    // Using ASM prune Adapt first and then decoder
    val classReader = new ClassReader(classBytesStream(templateFqdn))
    val classWriter = new ClassWriter(ClassWriter.COMPUTE_FRAMES)
    val classNode = new ClassNode()
    classReader.accept(classNode, ClassReader.EXPAND_FRAMES)

    def isUnusedField(fieldName: String): Boolean =
      useMap.get(fieldName) match {
        case Some(used) => !used
        case None => false
      }

    // Get rid of unused field members
    val fieldIter = classNode.fields.iterator()
    while (fieldIter.hasNext) {
      val fieldNode = fieldIter.next().asInstanceOf[FieldNode]
      val prefixedFieldName = fieldNode.name
      if (prefixedFieldName.startsWith(MemberPrefix)) {
        val fieldName = prefixedFieldName.substring(MemberPrefix.size)
        if (isUnusedField(fieldName)) {
          fieldIter.remove()
        }
      }
    }

    val methodIter = classNode.methods.iterator()
    while (methodIter.hasNext) {
      val methodNode = methodIter.next().asInstanceOf[MethodNode]
      val name = methodNode.name

      // Remove accessor method for unused field, we replace it with renamed
      // delegate method below
      if (isUnusedField(name)) {
        methodIter.remove()
      }

      // Rename or remove delegate methods
      if (name.startsWith(DelegatePrefix)) {
        val fieldName = name.substring(DelegatePrefix.size)
        if (useMap.contains(fieldName)) {
          if (useMap(fieldName)) { // used field, remove delegate function
            methodIter.remove()
          } else { // unused field, rename delegate
            methodNode.name = fieldName
          }
        }
      }

      // Remove setter methods for unused fields
      if (name.startsWith(SetterPrefix)) {
        val fieldName = name.substring(SetterPrefix.size)
        if (isUnusedField(fieldName)) {
          methodIter.remove()
        }
      }
    }

    classNode.accept(classWriter)
    classWriter.toByteArray
  }