Class DynamicDispatchLibrary

All Implemented Interfaces:
NodeInterface, Cloneable

public abstract class DynamicDispatchLibrary extends Library
A library that allows to dynamically dispatch to export library classes. Sometimes the target exports for a receiver type cannot be statically determined by the receiver class with the ExportLibrary annotation. To allow such types to dynamically dispatch to exports the dynamic dispatch library can be exported instead. By exporting dynamic dispatch the export target can be chosen dynamically.

The dynamic dispatch library requires to implement the dispatch method. The dispatch method returns the target exports class that this receiver should dispatch to. If it returns null then the type will dispatch to the library default exports. The implementation of the dispatch must be stable for a single receiver value. For example it is not allowed to change the dispatch target for a receiver instance. If the dispatch target was changed while the receiver was used by a library then an AssertionError will be thrown.

Full usage example

 @ExportLibrary(DynamicDispatchLibrary.class)
 static final class DispatchObject {

     final Object data;
     final Class<?> dispatchTarget;

     DispatchObject(Object data, Class<> dispatchTarget) {
         this.data = data;
         this.dispatchTarget = dispatchTarget;
     }

     @ExportMessage
     Class<?> dispatch() {
         return dispatchTarget;
     }
 }

 @GenerateLibrary
 public abstract static class ArrayLibrary extends Library {

     public boolean isArray(Object receiver) {
         return false;
     }

     public abstract int read(Object receiver, int index);
 }

 @ExportLibrary(value = ArrayLibrary.class, receiverType = DispatchObject.class)
 static final class DispatchedBufferArray {

     @ExportMessage
     static boolean isArray(DispatchObject o) {
         return true;
     }

     @ExportMessage
     static int read(DispatchObject o, int index) {
         return ((int[]) o.data)[index];
     }
 }

 public static void main(String[] args) {
     ArrayLibrary arrays = LibraryFactory.resolve(ArrayLibrary.class).getUncached();
     assert 42 == arrays.read(new DispatchObject(new int[]{42}, DispatchedBufferArray.class), 0);
 }
 
Since:
19.0
  • Constructor Details

    • DynamicDispatchLibrary

      protected DynamicDispatchLibrary()
      Constructor for generated subclasses. Subclasses of this class are generated, do not extend this class directly.
      Since:
      19.0
  • Method Details

    • dispatch

      public Class<?> dispatch(Object receiver)
      Returns a class that exports at least one library with an explicit receiver. Returns null to indicate that the default dispatch of the library should be used.
      Since:
      19.0
    • cast

      public abstract Object cast(Object receiver)
      Cast the object receiver type to the dispatched type. This is not supposed to be implemented by dynamic dispatch implementer but is automatically implemented when implementing dynamic dispatch.
      Since:
      19.0
    • getFactory

      public static LibraryFactory<DynamicDispatchLibrary> getFactory()
      Returns the library factory for DynamicDispatchLibrary.
      Since:
      19.0