Package: org.codehaus.groovy.classgen.asm.sc

## [Java] Interface AbstractFunctionalInterfaceWriter

-     public interface AbstractFunctionalInterfaceWriter

  Shared bytecode and deserialization support for statically-compiled functional interface implementations, including both lambdas and method references.

  Since:
    3.0.0

- - ### Nested Class Summary

    Nested classes
    Modifiers | Name | Description
    --- | --- | ---
    `record` | `AbstractFunctionalInterfaceWriter.SerializedLambdaFingerprint` | Compile-time identity of one serialized functional-interface target used by `$deserializeLambda$` dispatch.

  - ### Methods Summary

    Methods
    Type Params | Return Type | Name and description
    --- | --- | ---
    `` | `public void` | `addDeserializeDispatcherEntry(WriterController controller, Parameter[] deserializeMethodParameters, AbstractFunctionalInterfaceWriter.SerializedLambdaFingerprint serializedLambdaFingerprint, MethodNode helperMethod)` Registers a deserialization guard that routes a serialized lambda back to its helper method.
    `` | `private public Expression` | `allMatch(Expression expressions)` Combines predicates with logical AND.
    `` | `public ClassNode` | `convertParameterType(ClassNode targetType, ClassNode parameterType, ClassNode inferredType)` Reconciles the inferred lambda parameter type with the target functional-interface parameter type.
    `` | `private public org.objectweb.asm.Handle` | `createBootstrapMethod(boolean useAlt)`
    `` | `private public Object[]` | `createBootstrapMethodArguments(String samMethodDescriptor, int implMethodKind, ClassNode implClassNode, MethodNode implMethodNode, Parameter[] implMethodParameters, boolean serializable, ClassNode[] markers)` GROOVY-11998: builds the variadic args for `LambdaMetafactory.altMetafactory` including `FLAG_MARKERS` when the cast target is an intersection.
    `` | `public Parameter` | `createCapturedReceiverParameter(ClassNode receiverType, String parameterName)` Creates the synthetic parameter that carries a captured receiver into a generated lambda factory.
    `` | `public Parameter[]` | `createDeserializeMethodParameters()` Creates the parameter list for a synthetic `$deserializeLambda$` helper.
    `` | `public String` | `createFunctionalInterfaceFactoryDescriptor(ClassNode functionalType, Parameter[] capturedParameters)` Returns the invoked type descriptor used to create the functional-interface instance.
    `` | `private public org.objectweb.asm.Type` | `createInstantiatedMethodType(String samMethodDescriptor, MethodNode implMethodNode, Parameter[] implMethodParameters)`
    `` | `private public Statement` | `createInvalidDeserializationStatement()`
    `` | `public String` | `createMethodDescriptor(MethodNode method)` Returns the JVM method descriptor for the supplied method node.
    `` | `public String` | `createMethodDescriptor(ClassNode returnType, Parameter[] parameters)` Returns the JVM method descriptor for the supplied return type and parameters.
    `` | `public AbstractFunctionalInterfaceWriter.SerializedLambdaFingerprint` | `createSerializedLambdaFingerprint(String samMethodDescriptor, ClassNode capturingClass, int implMethodKind, ClassNode implClassNode, MethodNode implMethodNode, Parameter[] implMethodParameters, ClassNode functionalType, MethodNode abstractMethod, int capturedArgumentCount)` Builds the serialized-lambda fingerprint used to dispatch deserialization helpers.
    `` | `private public BlockStatement` | `getOrAddDeserializeDispatcherGuards(WriterController controller, Parameter[] deserializeMethodParameters)`
    `` | `private public Expression` | `matchesSerializedFormInt(Expression serializedForm, String accessorName, int expectedValue)`
    `` | `private public Expression` | `matchesSerializedFormString(Expression serializedForm, String accessorName, String expectedValue)`
    `` | `private public Expression` | `matchesSerializedFunctionalInterface(Expression serializedForm, AbstractFunctionalInterfaceWriter.SerializedLambdaFingerprint serializedLambdaFingerprint)` Builds the identity check used by `$deserializeLambda$` to select the correct synthetic helper for a serialized lambda/method reference.
    `` | `private public MethodCallExpression` | `serializedLambdaAccessorCall(Expression serializedForm, String accessorName)` Creates a direct SerializedLambda accessor call for the generated deserialization dispatcher.
    `` | `public void` | `writeFunctionalInterfaceIndy(org.objectweb.asm.MethodVisitor methodVisitor, String samMethodName, String invokedTypeDescriptor, String samMethodDescriptor, int implMethodKind, ClassNode implClassNode, MethodNode implMethodNode, Parameter[] implMethodParameters, boolean serializable)` Emits the bootstrap invocation for a functional-interface implementation without additional marker interfaces.
    `` | `public void` | `writeFunctionalInterfaceIndy(org.objectweb.asm.MethodVisitor methodVisitor, String samMethodName, String invokedTypeDescriptor, String samMethodDescriptor, int implMethodKind, ClassNode implClassNode, MethodNode implMethodNode, Parameter[] implMethodParameters, boolean serializable, ClassNode[] markers)` Marker-aware variant for intersection-cast targets such as `(Runnable & Cloneable) () -> ...`.

- - ### Method Detail

    - #### public void addDeserializeDispatcherEntry(WriterController controller, Parameter[] deserializeMethodParameters, AbstractFunctionalInterfaceWriter.SerializedLambdaFingerprint serializedLambdaFingerprint, MethodNode helperMethod)

      Registers a deserialization guard that routes a serialized lambda back to its helper method.

    - #### private public Expression allMatch(Expression expressions)

      Combines predicates with logical AND.

      throws:
        IllegalArgumentException if no predicates are supplied
      Parameters:
        `expressions` - match predicates to combine
      Returns:
        conjunction of all predicates

    - #### public ClassNode convertParameterType(ClassNode targetType, ClassNode parameterType, ClassNode inferredType)

      Reconciles the inferred lambda parameter type with the target functional-interface parameter type.

    - #### private public org.objectweb.asm.Handle createBootstrapMethod(boolean useAlt)

    - #### private public Object[] createBootstrapMethodArguments(String samMethodDescriptor, int implMethodKind, ClassNode implClassNode, MethodNode implMethodNode, Parameter[] implMethodParameters, boolean serializable, ClassNode[] markers)

      GROOVY-11998: builds the variadic args for `LambdaMetafactory.altMetafactory` including `FLAG_MARKERS` when the cast target is an intersection. Layout per the JDK contract:

             samMethodType, implMethod, instantiatedMethodType,
             flags,
             [markerCount, marker_1, ..., marker_n]   // when FLAG_MARKERS set
             [bridgeCount, bridge_1, ..., bridge_n]   // when FLAG_BRIDGES set (unused)

    - #### public Parameter createCapturedReceiverParameter(ClassNode receiverType, String parameterName)

      Creates the synthetic parameter that carries a captured receiver into a generated lambda factory.

    - #### public Parameter[] createDeserializeMethodParameters()

      Creates the parameter list for a synthetic `$deserializeLambda$` helper.

    - #### public String createFunctionalInterfaceFactoryDescriptor(ClassNode functionalType, Parameter[] capturedParameters)

      Returns the invoked type descriptor used to create the functional-interface instance.

    - #### private public org.objectweb.asm.Type createInstantiatedMethodType(String samMethodDescriptor, MethodNode implMethodNode, Parameter[] implMethodParameters)

    - #### private public Statement createInvalidDeserializationStatement()

    - #### public String createMethodDescriptor(MethodNode method)

      Returns the JVM method descriptor for the supplied method node.

    - #### public String createMethodDescriptor(ClassNode returnType, Parameter[] parameters)

      Returns the JVM method descriptor for the supplied return type and parameters.

    - #### public AbstractFunctionalInterfaceWriter.SerializedLambdaFingerprint createSerializedLambdaFingerprint(String samMethodDescriptor, ClassNode capturingClass, int implMethodKind, ClassNode implClassNode, MethodNode implMethodNode, Parameter[] implMethodParameters, ClassNode functionalType, MethodNode abstractMethod, int capturedArgumentCount)

      Builds the serialized-lambda fingerprint used to dispatch deserialization helpers.

    - #### private public BlockStatement getOrAddDeserializeDispatcherGuards(WriterController controller, Parameter[] deserializeMethodParameters)

    - #### private public Expression matchesSerializedFormInt(Expression serializedForm, String accessorName, int expectedValue)

    - #### private public Expression matchesSerializedFormString(Expression serializedForm, String accessorName, String expectedValue)

    - #### private public Expression matchesSerializedFunctionalInterface(Expression serializedForm, AbstractFunctionalInterfaceWriter.SerializedLambdaFingerprint serializedLambdaFingerprint)

      Builds the identity check used by `$deserializeLambda$` to select the correct synthetic helper for a serialized lambda/method reference.

      The generated expression is a conjunction over all stable SerializedLambda identity fields we emit via createSerializedLambdaFingerprint(String, ClassNode, int, ClassNode, MethodNode, Parameter[], ClassNode, MethodNode, int): capturing class, implementation kind/class/name/signature, functional interface class/SAM method/signature, instantiated method type, and captured argument count.

      Do not weaken this predicate (for example, by checking only method name/class or by returning a constant). Doing so can misroute deserialization to the wrong helper, while overly strict constant-false behavior breaks valid deserialization.

      Parameters:
        `serializedForm` - the deserialized `SerializedLambda` expression
        `serializedLambdaFingerprint` - compile-time fingerprint of one serialized lambda target
      Returns:
        expression that evaluates to `true` only for this exact target

    - #### private public MethodCallExpression serializedLambdaAccessorCall(Expression serializedForm, String accessorName)

      Creates a direct SerializedLambda accessor call for the generated deserialization dispatcher.

      The dispatcher is emitted during bytecode generation rather than type checking, so it must resolve accessor targets explicitly instead of relying on a later static-type-checking pass. This keeps the generated bytecode on the direct invocation path and prevents accidental fallback to Groovy's dynamic method dispatch for JDK accessors.

      throws:
        IllegalArgumentException if the accessor does not exist on `SerializedLambda`
      Parameters:
        `serializedForm` - the deserialized `SerializedLambda` expression
        `accessorName` - the zero-argument accessor to invoke
      Returns:
        method call expression with a resolved direct-call target

    - #### public void writeFunctionalInterfaceIndy(org.objectweb.asm.MethodVisitor methodVisitor, String samMethodName, String invokedTypeDescriptor, String samMethodDescriptor, int implMethodKind, ClassNode implClassNode, MethodNode implMethodNode, Parameter[] implMethodParameters, boolean serializable)

      Emits the bootstrap invocation for a functional-interface implementation without additional marker interfaces.

    - #### public void writeFunctionalInterfaceIndy(org.objectweb.asm.MethodVisitor methodVisitor, String samMethodName, String invokedTypeDescriptor, String samMethodDescriptor, int implMethodKind, ClassNode implClassNode, MethodNode implMethodNode, Parameter[] implMethodParameters, boolean serializable, ClassNode[] markers)

      Marker-aware variant for intersection-cast targets such as `(Runnable & Cloneable) () -> ...`. Markers are threaded through `LambdaMetafactory.altMetafactory` via `FLAG_MARKERS` so the generated lambda implements every component interface at runtime.

      Since:
        6.0.0