@Retention(value=RUNTIME) @Target(value=TYPE) public @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.
@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
.
Deprecated
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.
to specify default exports.
,
to make messages abstract if they have a default implemetnation
Modifier and Type | Optional Element and Description |
---|---|
Class<? extends Library> |
assertions
Specifies an assertion wrapper class that can be used to verify pre and post conditions of a
library.
|
boolean |
defaultExportLookupEnabled
Allows the library to lookup additional default exports using a service provider interface.
|
boolean |
dynamicDispatchEnabled
Allows the use of
DynamicDispatchLibrary with this library. |
boolean |
pushEncapsulatingNode
Enables push and pop of the encapsulating node when a library transitions from cached to
uncached.
|
Class<?> |
receiverType
Restricts the receiver type for exports that implement this library.
|
public abstract Class<? extends Library> assertions
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); } } }
public abstract Class<?> receiverType
public abstract boolean defaultExportLookupEnabled
Exports
for this library with explicit receiver type will automatically
be interpreted as additional default exports. External default exports may specify with the
priority
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. In order for this
to work the exported library must be registered using the
TruffleLanguage.Registration.defaultLibraryExports()
or
TruffleInstrument.Registration#defaultLibraryExports
.ExportLibrary.priority()
public abstract boolean dynamicDispatchEnabled
DynamicDispatchLibrary
with this library. By default dynamic
dispatch is enabled. If this flag is set to false
then the
dispatch
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.public abstract boolean pushEncapsulatingNode
EncapsulatingNodeReference