Simple JVM bytecode generation.
Simple JVM bytecode generation.
The bytecode version to use for types if unspecified.
The bytecode version to use for types if unspecified.
The class/interface flags to use if unspecified.
The class/interface flags to use if unspecified.
The field flags to use if unspecified.
The field flags to use if unspecified.
The constructor flags to use if unspecified.
The constructor flags to use if unspecified.
The method flags to use if unspecified.
The method flags to use if unspecified.
(define t)
(define cl t)
Return a Class object from the provided type.
Return a Class object from the provided type.
(get-bytes t)
Return a representation of the provided type as an array of bytes. This array is an in-memory equivalent to a java .class file on disk.
Return a representation of the provided type as an array of bytes. This array is an in-memory equivalent to a java .class file on disk.
(load-type cl t)
Return a class object from the given map containing the class :bytes and :name.
Return a class object from the given map containing the class :bytes and :name.
(new-instance t)
(new-instance t & args)
Define and return an instance of the generated class. The
non-abstract type must define a public constructor that accepts
either no arguments, or if args
is provided, the given arguments.
If the given argument count matches a constructor with a distinct arity, that one is invoked. In this case, constructors that take primitives are supported via reflective unboxing.
Otherwise, the argument types must exactly match (as per
clojure.core/class
) a defined constructor, or a constructor that
accepts the same amount of Object
s.
Define and return an instance of the generated class. The non-abstract type must define a public constructor that accepts either no arguments, or if `args` is provided, the given arguments. If the given argument count matches a constructor with a distinct arity, that one is invoked. In this case, constructors that take primitives are supported via reflective unboxing. Otherwise, the argument types must exactly match (as per `clojure.core/class`) a defined constructor, or a constructor that accepts the same amount of `Object`s.
(visit t)
Generate the class bytecode from the provided type map. Returns a map of the classes' :name and :bytes. Options:
:name of the class. Optional, but see below.
:flags seq of class/interface modifier flags (e.g., :final).
See the insn.util
namespace.
:super defaults to Object.
:interfaces sequence of interface types to extend/implement.
:annotations map or sequence of tuples, described below.
:signature generic type information - usually only ever needed for interop with Java libraries (reflection, etc.)
:fields sequence of field maps, described below.
:methods sequence of method maps, described below.
:version bytecode version given as a integer. For backwards compatibility, a float of major.minor may be given for versions 1.1 through 1.8.
:source string denoting the original source file - optional.
:debug string of arbitrary debug information - optional.
Each field and method can also be given :annotations and a :signature as per above.
Some examples:
(visit {:flags #{:public :interface} :name 'my.ns.Foo :methods [{:flags #{:public :abstract} :name :my_method :desc [:int]}]}) (visit {:flags #{:public} :name 'my.ns.Bar :interfaces ['my.ns.Foo] :methods [{:flags #{:public} :name :toString :desc [String] :emit [[:ldc "Bar"] [:areturn]]} {:flags #{:public} :name :my_method :desc [:int] :emit [[:ldc 42] [:ireturn]]}]})
Class instance/static fields are provided as maps. Options:
:name field name (required).
:type field type (required).
:flags seq of field modifier flags.
:value initial value. Only for primitive and String static fields, and if given, must be a corresponding Integer, Float, Long, Double, or String value.
Some example maps:
{:flags #{:public :final}, :name :my_string, :type String} {:flags #{:static}, :name :some_number, :type :long, :value 42}
Class/interface methods, constructors, and static initializers are provided as maps. Options:
:name method name (required). Can be either :init or :clinit, designating a constructor or the static initializer, respectively.
:flags seq of method modifier flags. Ignored for the static initializer.
:desc method parameter types and return type (specified last). Ignored for the static initializer, optional for constructors. For constructors, the method return type is forced to void if not explicitly specified as such.
:emit either a fn taking a MethodVisitor or a sequence of
instructions to emit for the method (see insn.op
).
Optional if method is abstract.
Some example maps, :emit has been omitted for brevity:
{:name :add_ints, :desc [:int :int :int]} {:flags #{:private}, :name :init, :desc [String :boolean :void]} {:name :clinit}
Additionally, methods may be given :parameter-annotations provided as a map of {parameter-index annotations}.
If the class name is not package prefixed, the current namespace is used as the resulting classes' package. If a name is not given, a generated (gensym) class name is used, qualified by the current namespace.
If the type does not define at least one constructor, and is not an abstract type, a default, zero-argument constructor with default access will be written that simply invokes the superclass constructor.
All annotations are provided as a map or sequence of tuples. Each key is the Annotation name and each value is a map of elements. A non-map value specifies a single element named :value as per java.
Annotation values are processed the same as in clojure. See: https://clojure.org/reference/datatypes#_java_annotation_support
Generate the class bytecode from the provided type map. Returns a map of the classes' :name and :bytes. Options: :name of the class. Optional, but see below. :flags seq of class/interface modifier flags (e.g., :final). See the `insn.util` namespace. :super defaults to Object. :interfaces sequence of interface types to extend/implement. :annotations map or sequence of tuples, described below. :signature generic type information - usually only ever needed for interop with Java libraries (reflection, etc.) :fields sequence of field maps, described below. :methods sequence of method maps, described below. :version bytecode version given as a integer. For backwards compatibility, a float of major.minor may be given for versions 1.1 through 1.8. :source string denoting the original source file - optional. :debug string of arbitrary debug information - optional. Each field and method can also be given :annotations and a :signature as per above. Some examples: (visit {:flags #{:public :interface} :name 'my.ns.Foo :methods [{:flags #{:public :abstract} :name :my_method :desc [:int]}]}) (visit {:flags #{:public} :name 'my.ns.Bar :interfaces ['my.ns.Foo] :methods [{:flags #{:public} :name :toString :desc [String] :emit [[:ldc "Bar"] [:areturn]]} {:flags #{:public} :name :my_method :desc [:int] :emit [[:ldc 42] [:ireturn]]}]}) Class instance/static fields are provided as maps. Options: :name field name (required). :type field type (required). :flags seq of field modifier flags. :value initial value. Only for primitive and String static fields, and if given, must be a corresponding Integer, Float, Long, Double, or String value. Some example maps: {:flags #{:public :final}, :name :my_string, :type String} {:flags #{:static}, :name :some_number, :type :long, :value 42} Class/interface methods, constructors, and static initializers are provided as maps. Options: :name method name (required). Can be either :init or :clinit, designating a constructor or the static initializer, respectively. :flags seq of method modifier flags. Ignored for the static initializer. :desc method parameter types and return type (specified last). Ignored for the static initializer, optional for constructors. For constructors, the method return type is forced to void if not explicitly specified as such. :emit either a fn taking a MethodVisitor or a sequence of instructions to emit for the method (see `insn.op`). Optional if method is abstract. Some example maps, :emit has been omitted for brevity: {:name :add_ints, :desc [:int :int :int]} {:flags #{:private}, :name :init, :desc [String :boolean :void]} {:name :clinit} Additionally, methods may be given :parameter-annotations provided as a map of {parameter-index annotations}. If the class name is not package prefixed, the current namespace is used as the resulting classes' package. If a name is not given, a generated (gensym) class name is used, qualified by the current namespace. If the type does not define at least one constructor, and is not an abstract type, a default, zero-argument constructor with default access will be written that simply invokes the superclass constructor. All annotations are provided as a map or sequence of tuples. Each key is the Annotation name and each value is a map of elements. A non-map value specifies a single element named :value as per java. Annotation values are processed the same as in clojure. See: https://clojure.org/reference/datatypes#_java_annotation_support
(write t)
(write t root)
Takes a map specifying a classes' :name and :bytes. Writes the class
bytes to a .class file. The file's directory is taken from its
package, its filename from its name, rooted at root
.
If not given, root
defaults to *compile-path*
, or if not set, the
"java.io.tmpdir" property. If both of those are not set, a 'classes'
directory in the current directory is used.
Takes a map specifying a classes' :name and :bytes. Writes the class bytes to a .class file. The file's directory is taken from its package, its filename from its name, rooted at `root`. If not given, `root` defaults to `*compile-path*`, or if not set, the "java.io.tmpdir" property. If both of those are not set, a 'classes' directory in the current directory is used.
cljdoc is a website building & hosting documentation for Clojure/Script libraries
× close