All Downloads are FREE. Search and download functionalities are using the official Maven repository.

miksilo.modularLanguages.deltas.bytecode.readJar.ParseKnownAttributes.scala Maven / Gradle / Ivy

The newest version!
package miksilo.modularLanguages.deltas.bytecode.readJar

import miksilo.modularLanguages.core.deltas.{Contract, DeltaWithPhase}
import miksilo.languageServer.core.language.Compilation
import miksilo.modularLanguages.core.node.Node
import miksilo.modularLanguages.deltas.bytecode.ByteCodeSkeleton
import miksilo.modularLanguages.deltas.bytecode.ByteCodeSkeleton._
import miksilo.modularLanguages.deltas.bytecode.attributes.UnParsedAttribute.UnParsedAttribute
import miksilo.modularLanguages.deltas.bytecode.attributes.{AttributeNameKey, ByteCodeAttribute, UnParsedAttribute}
import miksilo.modularLanguages.deltas.bytecode.constants.Utf8ConstantDelta

object ParseKnownAttributes extends DeltaWithPhase {

  override def description: String = "In the initial parsing of bytecode, the attributes are not parsed. " +
    "This phase parses the attributes, but only if the attribute type is known by the compiler."

  override def dependencies: Set[Contract] = Set[Contract](UnParsedAttribute, Utf8ConstantDelta)

  override def transformProgram(program: Node, compilation: Compilation): Unit = {
    val constantPool = program.constantPool
    program.visit(node => node.shape match {
          case UnParsedAttribute.Shape =>
            val typedNode = new UnParsedAttribute.UnParsedAttribute(node)
            val index = typedNode.nameIndex
            val name = constantPool.getValue(index).asInstanceOf[Node]
            val attributeTypeOption = ByteCodeSkeleton.attributesByName.get(compilation).get(Utf8ConstantDelta.get(name))
            for(attributeType <- attributeTypeOption)
            {
              parseAttribute(typedNode, attributeType)
            }
          case _ =>
        })
  }

  def parseAttribute(typedNode: UnParsedAttribute, attributeType: ByteCodeAttribute): Unit = {
    val parseWithoutNameIndex: ClassFileParser.Parser[Node] = attributeType.getParser(typedNode.node)
    val parser = parseWithoutNameIndex.map(node => {
      node(AttributeNameKey) = typedNode.nameIndex
      node
    })
    val inputBytes = typedNode.data.toArray
    val parseResult = ClassFileParser.phrase(parser)(new ByteReader(inputBytes))
    val newNode = parseResult.get
    typedNode.node.replaceData(newNode)
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy