Annotation Interface GenerateLibrary
public
and abstract
Java classes that
extend the Library class and are annotated by @GenerateLibrary
. A
library consists of a set of messages, that are specified using public Java methods. The methods
may be abstract or use default implementations. The first parameter of every library message is
the receiver parameter, which must be a non-primitive type and consistent across all messages of
a library. There are no restrictions on the return type or argument types of a message. Every
method that specifies a message must have a name that is unique per library. Final or private
methods will always be ignored by the generator. Parameter type overloading is currently not
supported for messages, therefore every public method must have a unique name per library.
Generic type arguments local to messages are generally supported, but generic type arguments on
the library type are not yet supported.
Basic Usage
The following example specifies a basic library for arrays:@GenerateLibrary public abstract class ArrayLibrary extends Library { public boolean isArray(Object receiver) { return false; } public abstract int read(Object receiver, int index); }Messages that are not implemented and have no default implementation throw an
AbstractMethodError
. The GenerateLibrary.Abstract
annotation can be used, to provide a default
implementation for receiver types but at the same time make the message abstract.
A library class may also specify default exports
that can be used to
dispatch to receiver types that don't export the library. Since the receiver type for default
exports can be specified explicitly, it can be used to provide a default implementation for
receiver types of third parties or the JDK. For example the Truffle interop library has default
exports for most Number
types, String
and Boolean
type.
In order to enable AOT generation for a a library annotate the class with GenerateAOT
and
enable exports to be used for AOT by setting ExportLibrary.useForAOT()
to
true
.
Deprecating Messages
If a library message gets deprecated using theDeprecated
annotation then all exports
will get a deprecation warning. This can be useful to evolve libraries over time in a compatible
way.
Sometimes it is needed to remove or modify types of parameters as part of evolution. In this case
it is possible to declare multiple overloads of the same library message where all but one method
are annotated with Deprecated
. The non-deprecated method must use more generic or the
same parameter types. For example, this allows to evolve message with parameter String
to
evolve into Object
. It is also possible to add or remove parameter types in the
non-deprecated method. These restrictions are necessary in order to ensure that exports of that
message never export the new overload after recompilation unless the parameter types were
updated.
- Since:
- 19.0
- See Also:
-
Nested Class Summary
Modifier and TypeClassDescriptionstatic @interface
Makes a library message abstract, but allows to keep a default implementation.static @interface
Specifieslibrary
implementations provided by default as a fallback. -
Optional Element Summary
Modifier and TypeOptional ElementDescriptionSpecifies an assertion wrapper class that can be used to verify pre and post conditions of a library.boolean
Allows the library to lookup additional default exports using a service provider interface.boolean
Allows the use ofDynamicDispatchLibrary
with this library.boolean
Enables push and pop of the encapsulating node when a library transitions from cached to uncached.Class
<?> Restricts the receiver type for exports that implement this library.
-
Element Details
-
assertions
Specifies an assertion wrapper class that can be used to verify pre and post conditions of a library. Assertion wrappers are only inserted when assertions (-ea) are enabled. It is required that assertion wrappers don't introduce additional side-effects and call the delegate methods exactly once. If assertions are disabled no library wrapper will be inserted therefore not performing any checks when library messages are invoked.Example Usage:
@GenerateLibrary(assertions = ArrayAssertions.class) public abstract class ArrayLibrary extends Library { public boolean isArray(Object receiver) { return false; } public int read(Object receiver, int index) { throw new UnsupportedOperationException(); } static class ArrayAssertions extends ArrayLibrary { @Child private ArrayLibrary delegate; ArrayAssertions(ArrayLibrary delegate) { this.delegate = delegate; } @Override public boolean isArray(Object receiver) { return delegate.isArray(receiver); } @Override public int read(Object receiver, int index) { int result = super.read(receiver, index); assert delegate.isArray(receiver) : "if a read was successful the receiver must be an array"; return result; } @Override public boolean accepts(Object receiver) { return delegate.accepts(receiver); } } }
- Since:
- 19.0
- Default:
com.oracle.truffle.api.library.Library.class
-
receiverType
Class<?> receiverTypeRestricts the receiver type for exports that implement this library. This allows to have different receiver type in message methods, but require export receiver types to implement or extend a declared class. Default exports are not affected by this restriction and can therefore export the library for any receiver type the message methods first parameter is compatible with.- Since:
- 19.0
- Default:
java.lang.Object.class
-
defaultExportLookupEnabled
boolean defaultExportLookupEnabledAllows the library to lookup additional default exports using a service provider interface.Exports
for this library with explicit receiver type will automatically be interpreted as additional default exports. External default exports may specify with thepriority
whether they are looked up before or after existing default exports specified for the library. Default exports always have a lower priority than explicit exports on the receiver type or exports that use dynamic dispatch.- Since:
- 20.1
- See Also:
- Default:
false
-
dynamicDispatchEnabled
boolean dynamicDispatchEnabledAllows the use ofDynamicDispatchLibrary
with this library. By default dynamic dispatch is enabled. If this flag is set tofalse
then thedispatch
method will not be used for this library. Only default exports and exports declared with the receiver type will be used instead for this library.- Since:
- 20.1
- Default:
true
-
pushEncapsulatingNode
boolean pushEncapsulatingNodeEnables push and pop of the encapsulating node when a library transitions from cached to uncached. The current encapsulating node is needed for correct stack trace location when library exports perform guest language calls. If a library is known to never need correct stack trace information, e.g. if all exports are known to not perform guest language calls, then pushing and popping of encapsulating nodes can be disabled. By default pushing and popping of encapsulating nodes is enabled.- Since:
- 20.3
- See Also:
- Default:
true
-