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

org.opalj.bi.reader.AttributesReader.scala Maven / Gradle / Ivy

The newest version!
/* BSD 2-Clause License - see OPAL/LICENSE for details. */
package org.opalj
package bi
package reader

import java.io.DataInputStream

import org.opalj.collection.immutable.RefArray
import org.opalj.control.fillRefArray

/**
 * Trait that implements a template method to read in the attributes of
 * a class, method_info, field_info or code_attribute structure.
 */
trait AttributesReader
    extends AttributesAbstractions
    with Constant_PoolAbstractions
    with Unknown_attributeAbstractions {

    //
    // TYPE DEFINITIONS AND FACTORY METHODS
    //

    /**
     * This factory method is called if an attribute is encountered that is unknown.
     * In general, such unknown attributes are represented by the
     * Unknown_attribute class.
     * However, if no representation of the unknown attribute is needed this method
     * can return `null` - after reading (skipping) all bytes belonging to this attribute.
     * If `null` is returned all information regarding this attribute are thrown away.
     */
    def Unknown_attribute(
        cp:                   Constant_Pool,
        ap:                   AttributeParent,
        ap_name_index:        Constant_Pool_Index,
        ap_descriptor_index:  Constant_Pool_Index,
        attribute_name_index: Int,
        in:                   DataInputStream
    ): Unknown_attribute

    //
    // IMPLEMENTATION
    //

    /**
     * This map associates attribute names with functions to read the corresponding
     * attribute
     *
     * ==Names of the Attributes==
     * Java 1/2Attributes:
*
    *
  • ConstantValue_attribute
  • *
  • Exceptions_attribute
  • *
  • InnerClasses_attribute
  • *
  • EnclosingMethod_attribute
  • *
  • Synthetic_attribute
  • *
  • SourceFile_attribute
  • *
  • LineNumberTable_attribute
  • *
  • LocalVariableTable_attribute
  • *
  • LocalVariableTypeTable_attribute
  • *
  • Deprecated_attribute
  • *
  • Code_attribute => (CodeReader)
  • *
* Java 5Attributes:
*
    *
  • Signature_attribute
  • *
  • SourceDebugExtension_attribute
  • *
  • RuntimeVisibleAnnotations_attribute
  • *
  • RuntimeInvisibleAnnotations_attribute
  • *
  • RuntimeVisibleParameterAnnotations_attribute
  • *
  • RuntimeInvisibleParameterAnnotations_attribute
  • *
  • AnnotationDefault_attribute
  • *
* Java 6Attributes:
*
    *
  • StackMapTable_attribute
  • *
* Java 7Attributes:
*
    *
  • BootstrapMethods_attribute
  • *
* Java 8Attributes:
*
    *
  • MethodParameters_attribute
  • *
  • RuntimeVisibleTypeAnnotations_attribute
  • *
  • RuntimeInvisibleTypeAnnotations_attribute
  • *
* Java 9Attributes:
*
    *
  • Module_attribute
  • *
  • MainClass_attribute
  • *
  • ModulePackages_attribute
  • *
* Java 11Attributes:
*
    *
  • NestHost_attribute
  • *
  • NestMembers_attribute
  • *
* Java 16Attributes:
*
    *
  • Record_attribute
  • *
* * The returned function is allowed to return null; in this case the attribute * will be discarded. */ private[this] var attributeReaders: Map[String, (Constant_Pool, AttributeParent, Constant_Pool_Index, Constant_Pool_Index, Constant_Pool_Index, DataInputStream) ⇒ Attribute] = Map() /** * See `AttributeReader.registerAttributeReader` for details. */ def registerAttributeReader( reader: (String, (Constant_Pool, AttributeParent, Constant_Pool_Index, Constant_Pool_Index, Constant_Pool_Index, DataInputStream) ⇒ Attribute) ): Unit = { attributeReaders += reader } private[this] var attributesPostProcessors = RefArray.empty[Attributes ⇒ Attributes] /** * Registers a new processor for the list of all attributes of a given class file * element (class, field, method, code). This can be used to post-process attributes. * E.g., to merge multiple line number tables if they exist or to link * attributes that have strong dependencies. E.g., (in Java 8) the * `localvar_target` structure of the `Runtime(In)VisibleTypeAnnotations` attribute * has a reference in the local variable table attribute. */ def registerAttributesPostProcessor(p: Attributes ⇒ Attributes): Unit = { attributesPostProcessors :+= p } def Attributes( cp: Constant_Pool, ap: AttributeParent, ap_name_index: Constant_Pool_Index, ap_descriptor_index: Constant_Pool_Index, in: DataInputStream ): Attributes = { val attributes: Attributes = fillRefArray(in.readUnsignedShort) { Attribute(cp, ap, ap_name_index, ap_descriptor_index, in) }.filterNonNull // lets remove the attributes we don't need or understand attributesPostProcessors.foldLeft(attributes)((a, p) ⇒ p(a)) } def Attribute( cp: Constant_Pool, ap: AttributeParent, ap_name_index: Constant_Pool_Index, ap_descriptor_index: Constant_Pool_Index, in: DataInputStream ): Attribute = { val attribute_name_index = in.readUnsignedShort() val attribute_name = cp(attribute_name_index).asString attributeReaders.getOrElse( attribute_name, Unknown_attribute _ // this is a factory method )(cp, ap, ap_name_index, ap_descriptor_index, attribute_name_index, in) } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy