Object

org.opalj.br.instructions

ClassFileFactory

Related Doc: package instructions

Permalink

object ClassFileFactory

Provides helper methods to facilitate the generation of classes. In particular, functionality to create transparent proxy classes is provided.

Linear Supertypes
AnyRef, Any
Ordering
  1. Alphabetic
  2. By Inheritance
Inherited
  1. ClassFileFactory
  2. AnyRef
  3. Any
  1. Hide All
  2. Show All
Visibility
  1. Public
  2. All

Value Members

  1. final def !=(arg0: Any): Boolean

    Permalink
    Definition Classes
    AnyRef → Any
  2. final def ##(): Int

    Permalink
    Definition Classes
    AnyRef → Any
  3. final def ==(arg0: Any): Boolean

    Permalink
    Definition Classes
    AnyRef → Any
  4. final val AlternativeFactoryMethodName: String("$createInstance")

    Permalink

    Alternative name for the factory method of proxy classes created by the Proxy method.

    Alternative name for the factory method of proxy classes created by the Proxy method. This name is only used if the proxified method's name is equal to DefaultFactoryMethodName.

  5. final val DefaultFactoryMethodName: String("$newInstance")

    Permalink

    This is the default name for the factory method of a proxy class that is created by the Proxy method.

    This is the default name for the factory method of a proxy class that is created by the Proxy method. If the name of the method to be proxified is equal to this name, AlternativeFactoryMethodName is used instead.

  6. def Proxy(definingType: TypeDeclaration, methodName: String, methodDescriptor: MethodDescriptor, receiverType: ObjectType, receiverIsInterface: Boolean, receiverMethodName: String, receiverMethodDescriptor: MethodDescriptor, invocationInstruction: Opcode, bridgeMethodDescriptor: Option[MethodDescriptor] = None): ClassFile

    Permalink

    Creates a class that acts as a proxy for the specified class.

    Creates a class that acts as a proxy for the specified class. The proxy implements a single method – e.g., as defined by a so-called "Functional Interface" - that calls the specified method; creating a proxy for java.lang.Object's methods is not supported. Additionally, further marker interfaces (e.g., java.io.Serializable) may be implemented.

    The generated class uses the following template:

    class <definingType.objectType>
     extends <definingType.theSuperclassType>
     implements <definingType.theSuperinterfaceTypes> {
    
     private final <ReceiverType> receiver;
    
     // possible additional fields for static parameters
    
     public ""( <ReceiverType> receiver) { // the constructor
         this.receiver = receiver;
     }
    
     public <methodDescriptor.returnType> <methodName> <methodDescriptor.parameterTypes>{
        return/*<= if the return type is not void*/ this.receiver.<receiverMethodName>(<parameters>)
     }
    
     // possibly a bridge method
    }

    The class, the constructor and the method are public. The field which holds the receiver object is private and final unless the receiver method is static. In this case no receiver field is generated and the constructor does not take an argument of the receiver's type.

    In addition to the receiver field, additional fields holding static parameters are created if all parameters found in methodDescriptor are present, in the same order, at the end of receiverMethodDescriptor's parameters, but receiverMethodDescriptor has more parameters that precede the parameters found in methodDescriptor.

    E.g., given the following two descriptors:

    val methodDescriptor =
     MethodDescriptor(IntegerType, IntegerType)
    val receiverMethodDescriptor =
     MethodDescriptor(IndexedSeq(DoubleType, IntegerType), IntegerType)

    one additional field and constructor parameter of type double will be created. This case occurs for example with Java 8 lambda expressions that capture local variables, which are prepended to the regular parameter list.

    If any of the parameters or the return type of methodDescriptor are generic types, the generated proxy will need to create a bridge method to be valid. Therefore, in these cases, bridgeMethodDescriptor must be specified. It must be identical to methodDescriptor except for all occurrences of generic types, which must be replaced with ObjectType.Object. For example, consider the Java interface java.util.Comparator that defines the generic type T and uses it in its int compare(T, T) method. This would require a bridge method int compare(Object, Object). The appropriate method descriptors for, for example, Comparator<String> would be:

    // Uses "String"
    methodDescriptor =
     MethodDescriptor(IndexedSeq(ObjectType.String, ObjectType.String), IntegerType)
    // Uses "Object"
    bridgeMethodDescriptor =
     MethodDescriptor(IndexedSeq(ObjectType.Object, ObjectType.Object), IntegerType)

    The created class will always have its synthetic access flag set, as well as the VirtualTypeFlag attribute.

    invocationInstruction

    the opcode of the invocation instruction (INVOKESPECIAL.opcode,INVOKEVIRTUAL.opcode, INVOKESTATIC.opcode,INVOKEINTERFACE.opcode) used to call call the method on the receiver.

    Note

    It is expected that methodDescriptor and receiverMethodDescriptor are "compatible", i.e. it would be possible to have the method described by methodDescriptor forward to receiverMethodDescriptor. This requires that for their return types, one of the following statements holds true: - methodDescriptor's return type is VoidType (so no returning is necessary) - receiverMethodDescriptor's return type is assignable to methodDescriptor's (e.g. a "smaller" numerical type, (un)boxable, a subtype, etc) - receiverMethodDescriptor returns Object: in this case, we assume that Object stands for "generic return type" and expect the receiver method to return an object of a type compatible to the forwarder method's return type Additionally, the parameter lists must satisfy one of these conditions: - they are identical - the descriptors have the same numbers of parameters and methodDescriptor's parameter types can be widened/boxed/unboxed to match receiverMethodDescriptor's parameter types - methodDescriptor's first parameter is of the same type as receiverType, and the remaining parameters are compatible to receiverMethodDescriptor's entire parameter list (this is, effectively, an explicit this and occurs for example with references to instance methods: e.g. String::isEmpty, a zero argument method, could be turned into the Predicate method test(String)) - the last n parameters of receiverMethodDescriptor are identical to the parameters of methodDescriptor, where n = methodDescriptor.parametersCount (this is the case if a lambda expression captures local variables) - receiverMethodDescriptor's single parameter is of type Object[] (in this case, methodDescriptor's arguments will be collected into an Object[] prior to forwarding) Examples of compatible method descriptors are:

    // ------------- First Example
    methodDescriptor =
     MethodDescriptor(IntegerType, VoidType)
    receiverMethodDescriptor =
     MethodDescriptor(ObjectType.Integer, VoidType)
     // or MethodDescriptor(ObjectType.Object, ByteType)
    // ------------- Second Example
    methodDescriptor =
     MethodDescriptor(ObjectType.String, BooleanType)
    receiverMethodDescriptor =
     MethodDescriptor.JustReturnsBoolean // IF receiverType == ObjectType.String
    // ------------- Third Example
    methodDescriptor =
     MethodDescriptor(IndexedSeq(ByteType, ByteType, ObjectType.Integer), IntegerType)
    receiverMethodDescriptor =
     MethodDescriptor(ArrayType.ArrayOfObject, ObjectType.Object) // generic method
    // ------------- Fourth Example
    methodDescriptor =
     MethodDescriptor(IntegerType, LongType)
    receiverMethodDescriptor =
     MethodDescriptor(IndexedSeq(ByteType, ByteType, IntegerType), IntegerType)
    ,

    The used class file version is 49.0 (Java 5) (Using this version, we are not required to create the stack map table attribute to create a valid class file.)

  7. final val ReceiverFieldName: String("$receiver")

    Permalink

    Name used to store the final receiver object in generated proxy classes.

  8. final def asInstanceOf[T0]: T0

    Permalink
    Definition Classes
    Any
  9. def callSuperDefaultConstructor(theSuperclassType: ObjectType): Array[Instruction]

    Permalink

    Returns the instructions necessary to perform a call to the constructor of the given superclass.

  10. def clone(): AnyRef

    Permalink
    Attributes
    protected[java.lang]
    Definition Classes
    AnyRef
    Annotations
    @throws( ... )
  11. def cloneMethodSignature: MethodSignature

    Permalink
  12. def copyParametersToInstanceFields(declaringType: ObjectType, fields: IndexedSeq[Field]): Array[Instruction]

    Permalink

    Creates an array of instructions that populates the given fields in declaringType from local variables (constructor parameters).

    Creates an array of instructions that populates the given fields in declaringType from local variables (constructor parameters).

    This method assumes that it creates instructions for a constructor whose parameter list matches the given fields in terms of order and field types.

    It further assumes that none of the fields provided as arguments are static fields, as it would make little sense to initialize static fields through the constructor.

  13. def createBridgeMethod(methodName: String, bridgeMethodDescriptor: MethodDescriptor, targetMethodDescriptor: MethodDescriptor, targetMethodDeclaringType: ObjectType): Method

    Permalink

    Creates a bridge method using the given method descriptors, name, and type.

    Creates a bridge method using the given method descriptors, name, and type.

    The bridge method's parameter list and return type are dictated by bridgeMethodDescriptor. This method generates bytecode that invokes the method described by methodName and targetMethodDescriptor on declaringType. If parameters need to be cast before invocation, the appropriate bytecode will be generated as well.

  14. def createConstructor(definingType: TypeDeclaration, fields: IndexedSeq[Field]): Method

    Permalink

    Creates a public constructor that initializes the given fields.

    Creates a public constructor that initializes the given fields.

    For every Field in fields the constructor will have one parameter of the same type. The parameter list will have the same order as fields. The generated constructor will call the superclass' default constructor; i.e., the type definingType.theSuperclassType has to have a default constructor. Additionally, bytecode is generated to populate the fields from the constructor arguments.

    See also

    copyParametersToInstanceFields

    callSuperDefaultConstructor

  15. def createFactoryMethod(typeToCreate: ObjectType, fieldTypes: IndexedSeq[FieldType], factoryMethodName: String): Method

    Permalink

    Creates a factory method with the appropriate instructions to create and return an instance of typeToCreate.

    Creates a factory method with the appropriate instructions to create and return an instance of typeToCreate.

    typeToCreate must have a constructor with a parameter list that exactly matches fieldTypes. It also must not define a method named factoryMethodName with a parameter list matching fieldTypes.

    See also

    createConstructor

  16. def createField(accessFlags: Int = ..., name: String, fieldType: FieldType, attributes: Seq[Attribute] = Seq.empty): Field

    Permalink

    Creates a field of the specified type with the given name.

  17. final def eq(arg0: AnyRef): Boolean

    Permalink
    Definition Classes
    AnyRef
  18. def equals(arg0: Any): Boolean

    Permalink
    Definition Classes
    AnyRef → Any
  19. def equalsMethodSignature: MethodSignature

    Permalink
  20. def finalize(): Unit

    Permalink
    Attributes
    protected[java.lang]
    Definition Classes
    AnyRef
    Annotations
    @throws( classOf[java.lang.Throwable] )
  21. def finalizeMethodSignature: MethodSignature

    Permalink
  22. final def getClass(): Class[_]

    Permalink
    Definition Classes
    AnyRef → Any
  23. def hashCode(): Int

    Permalink
    Definition Classes
    AnyRef → Any
  24. def hashCodeMethodSignature: MethodSignature

    Permalink
  25. final def isInstanceOf[T0]: Boolean

    Permalink
    Definition Classes
    Any
  26. def isNewInvokeSpecial(opcode: Opcode, methodName: String): Boolean

    Permalink

    Returns true if the method invocation described by the given Opcode and method name is a "NewInvokeSpecial" invocation (i.e.

    Returns true if the method invocation described by the given Opcode and method name is a "NewInvokeSpecial" invocation (i.e. a reference to a constructor, like so: Object::new).

  27. def isVirtualMethodReference(opcode: Opcode, targetMethodDeclaringType: ObjectType, targetMethodDescriptor: MethodDescriptor, proxyInterfaceMethodDescriptor: MethodDescriptor): Boolean

    Permalink

    Returns true if the given parameters identify a Java 8 method reference to an instance or interface method (i.e.

    Returns true if the given parameters identify a Java 8 method reference to an instance or interface method (i.e. a reference to a virtual method, like so: ArrayList::size or List::size). In this case, the resulting functional interface's method has one parameter more than the referenced method because the referenced method's implicit this parameter becomes explicit.

  28. final def ne(arg0: AnyRef): Boolean

    Permalink
    Definition Classes
    AnyRef
  29. def nonFinalInterfaceOfObject(): Array[MethodSignature]

    Permalink
  30. final def notify(): Unit

    Permalink
    Definition Classes
    AnyRef
  31. final def notifyAll(): Unit

    Permalink
    Definition Classes
    AnyRef
  32. def parameterForwardingInstructions(forwarderMethodDescriptor: MethodDescriptor, receiverMethodDescriptor: MethodDescriptor, variableOffset: Int, staticParameters: Seq[Field], definingType: ObjectType): Array[Instruction]

    Permalink

    Generates an array of instructions that fill the operand stack with all parameters required by receiverMethodDescriptor from the parameters of calledMethodDescriptor.

    Generates an array of instructions that fill the operand stack with all parameters required by receiverMethodDescriptor from the parameters of calledMethodDescriptor. For that reason, it is expected that both method descriptors have compatible parameter and return types: i.e., that forwarderMethodDescriptor's parameters can be widened or (un)boxed to fit into receiverMethodDescriptor's parameters, and that receiverMethodDescriptor's return type can be widened or (un)boxed to fit into forwarderMethodDescriptor's return type.

    If receiverMethodDescriptor has more parameters than forwarderMethodDescriptor, the missing parameters must be provided in staticParameters.

    See also

    org.opalj.br.instructions.LoadLocalVariableInstruction

  33. def proxyMethod(definingType: ObjectType, methodName: String, methodDescriptor: MethodDescriptor, staticParameters: Seq[Field], receiverType: ObjectType, receiverIsInterface: Boolean, receiverMethodName: String, receiverMethodDescriptor: MethodDescriptor, invocationInstruction: Opcode): Method

    Permalink

    Creates a proxy method with name methodName and descriptor methodDescriptor and the bytecode instructions to execute the method receiverMethod in receiverType.

    Creates a proxy method with name methodName and descriptor methodDescriptor and the bytecode instructions to execute the method receiverMethod in receiverType.

    If the methodDescriptors have to be identical in terms of parameter types and return type.

  34. def returnAndConvertInstructions(toBeReturnedType: FieldType, typeOnStack: FieldType): Array[Instruction]

    Permalink

    Returns the instructions that return a value of type typeToBeReturned, converting typeOnStack to it first if necessary.

    Returns the instructions that return a value of type typeToBeReturned, converting typeOnStack to it first if necessary. If typeOnStack is Object, it will be treated as a generic return type and converted to the required type.

    Annotations
    @throws( ... )
  35. final def synchronized[T0](arg0: ⇒ T0): T0

    Permalink
    Definition Classes
    AnyRef
  36. def toString(): String

    Permalink
    Definition Classes
    AnyRef → Any
  37. def toStringSignature: MethodSignature

    Permalink
  38. final def wait(): Unit

    Permalink
    Definition Classes
    AnyRef
    Annotations
    @throws( ... )
  39. final def wait(arg0: Long, arg1: Int): Unit

    Permalink
    Definition Classes
    AnyRef
    Annotations
    @throws( ... )
  40. final def wait(arg0: Long): Unit

    Permalink
    Definition Classes
    AnyRef
    Annotations
    @throws( ... )

Inherited from AnyRef

Inherited from Any

Ungrouped