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

org.opalj.br.MethodHandle.scala Maven / Gradle / Ivy

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

import org.opalj.bi.REF_getField
import org.opalj.bi.REF_getStatic
import org.opalj.bi.REF_invokeInterface
import org.opalj.bi.REF_invokeSpecial
import org.opalj.bi.REF_invokeStatic
import org.opalj.bi.REF_invokeVirtual
import org.opalj.bi.REF_newInvokeSpecial
import org.opalj.bi.REF_putField
import org.opalj.bi.REF_putStatic
import org.opalj.bi.ReferenceKind

/**
 * A method handle.
 *
 * @author Michael Eichberg
 */
sealed abstract class MethodHandle extends ConstantValue[MethodHandle] {

    final override def value: this.type = this

    /**
     * Returns `ObjectType.MethodHandle`;
     * the type of the value pushed onto the stack by an ldc(_w) instruction.
     */
    override def runtimeValueType: ObjectType = ObjectType.MethodHandle

    def isInvokeStaticMethodHandle: Boolean = false

    override def valueToString: String = this.toString

    def toJava: String

    def referenceKind: ReferenceKind
}

sealed abstract class FieldAccessMethodHandle extends MethodHandle {

    def declaringClassType: ObjectType
    def name: String
    def fieldType: FieldType

    def asVirtualField = VirtualField(declaringClassType, name, fieldType)

    override def toJava: String = {
        s"${getClass.getSimpleName}: ${declaringClassType.toJava}.$name:${fieldType.toJava}"
    }
}

sealed abstract class FieldReadAccessMethodHandle extends FieldAccessMethodHandle

sealed abstract class FieldWriteAccessMethodHandle extends FieldAccessMethodHandle

case class GetFieldMethodHandle(
        declaringClassType: ObjectType,
        name:               String,
        fieldType:          FieldType
) extends FieldReadAccessMethodHandle {
    override def referenceKind: ReferenceKind = REF_getField
}

case class GetStaticMethodHandle(
        declaringClassType: ObjectType,
        name:               String,
        fieldType:          FieldType
) extends FieldReadAccessMethodHandle {
    override def referenceKind: ReferenceKind = REF_getStatic
}

case class PutFieldMethodHandle(
        declaringClassType: ObjectType,
        name:               String,
        fieldType:          FieldType
) extends FieldWriteAccessMethodHandle {
    override def referenceKind: ReferenceKind = REF_putField
}

case class PutStaticMethodHandle(
        declaringClassType: ObjectType,
        name:               String,
        fieldType:          FieldType
) extends FieldWriteAccessMethodHandle {
    override def referenceKind: ReferenceKind = REF_putStatic
}

sealed abstract class MethodCallMethodHandle extends MethodHandle {

    def receiverType: ReferenceType
    def name: String
    def methodDescriptor: MethodDescriptor

    override def toJava: String = {
        s"${getClass.getSimpleName}: ${methodDescriptor.toJava(receiverType.toJava, name)}"
    }

    def opcodeOfUnderlyingInstruction: Opcode
}

object MethodCallMethodHandle {

    def unapply(
        handle: MethodCallMethodHandle
    ): Option[(ReferenceType, String, MethodDescriptor)] = {
        Some((handle.receiverType, handle.name, handle.methodDescriptor))
    }

}

case class InvokeVirtualMethodHandle(
        receiverType:     ReferenceType,
        name:             String,
        methodDescriptor: MethodDescriptor
) extends MethodCallMethodHandle {

    override def opcodeOfUnderlyingInstruction: Opcode = instructions.INVOKEVIRTUAL.opcode

    override def referenceKind: ReferenceKind = REF_invokeVirtual
}

case class InvokeStaticMethodHandle(
        receiverType:     ReferenceType,
        isInterface:      Boolean,
        name:             String,
        methodDescriptor: MethodDescriptor
) extends MethodCallMethodHandle {

    override def opcodeOfUnderlyingInstruction: Opcode = instructions.INVOKESTATIC.opcode

    final override def isInvokeStaticMethodHandle: Boolean = true

    override def referenceKind: ReferenceKind = REF_invokeStatic
}

case class InvokeSpecialMethodHandle(
        receiverType:     ReferenceType,
        isInterface:      Boolean,
        name:             String,
        methodDescriptor: MethodDescriptor
) extends MethodCallMethodHandle {

    override def opcodeOfUnderlyingInstruction: Opcode = instructions.INVOKESPECIAL.opcode

    override def referenceKind: ReferenceKind = REF_invokeSpecial
}

case class NewInvokeSpecialMethodHandle(
        receiverType:     ObjectType,
        methodDescriptor: MethodDescriptor
) extends MethodCallMethodHandle {

    final override val name = ""

    override def opcodeOfUnderlyingInstruction: Opcode = instructions.INVOKESPECIAL.opcode

    override def referenceKind: ReferenceKind = REF_newInvokeSpecial
}

case class InvokeInterfaceMethodHandle(
        receiverType:     ReferenceType,
        name:             String,
        methodDescriptor: MethodDescriptor
) extends MethodCallMethodHandle {

    override def opcodeOfUnderlyingInstruction: Opcode = instructions.INVOKEINTERFACE.opcode

    override def referenceKind: ReferenceKind = REF_invokeInterface
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy