Package org.codehaus.commons.compiler

# Interface IExpressionEvaluator

All Superinterfaces:
  `ICookable`, `IMultiCookable`

All Known Implementing Classes:
  `ExpressionEvaluator`, `ExpressionEvaluator`

public interface IExpressionEvaluator extends ICookable, IMultiCookable
An engine that evaluates expressions in JVM bytecode.

The syntax of the expression to compile is that of a Java expression, as defined in JLS7, section 15. Notice that a Java expression does not have a concluding semicolon.

Example:

       a + 7 * b

(Notice that this expression refers to two parameters "a" and "b", as explained below.)

The expression may optionally be preceeded with a sequence of import directives like

       import java.text.*;
       new DecimalFormat("####,###.##").format(10200020.345345)

(Notice that the import directive is concluded with a semicolon, while the expression is not.) This feature is not available if you compile many expressions at a time (see below).

To set up an `IExpressionEvaluator` object, proceed as follows:

1. Create an `IExpressionEvaluator`-derived class
2. Configure the `IExpressionEvaluator` by calling any of the following methods:

- `setExpressionType(Class)`
- `setParameters(String[], Class[])`
- `setThrownExceptions(Class[])`
- `setParentClassLoader(ClassLoader)`
- `setDefaultImports(String[])`

3. Call any of the `ICookable.cook(String, java.io.Reader)` methods to scan, parse, compile and load the expression into the JVM.

After the `IExpressionEvaluator` object is set up, the expression can be evaluated as often with different parameter values (see `evaluate(Object[])`). This evaluation is very fast, compared to the compilation.

Less common methods exist that allow for the specification of the name of the generated class, the class it extends, the interfaces it implements, the name of the method that executes the expression, the exceptions that this method (i.e. the expression) is allowed to throw, and the `ClassLoader` that is used to define the generated class and to load classes referenced by the expression.

If you want to compile many expressions at the same time, you have the option to cook an array of expressions in one `IExpressionEvaluator` by using the following methods:

- `setMethodNames(String[])`
- `setParameters(String[][], Class[][])`
- `setExpressionTypes(Class[])`
- `setStaticMethod(boolean[])`
- `setThrownExceptions(Class[][])`
- `IMultiCookable.cook(String[], Reader[])`
- `evaluate(int, Object[])`

Notice that these methods have array parameters in contrast to their one-expression brethren.

Notice that for functionally identical `IExpressionEvaluator`s, `Object.equals(java.lang.Object)` will return `true`. E.g. "a+b" and "c + d" are functionally identical if "a" and "c" have the same type, and so do "b" and "d".

'JLS7' refers to the Java Language Specification, Java SE 7 Edition.

## Field Summary

Fields
Modifier and Type
Field
Description
`static final Class<?>`
`ANY_TYPE`
Deprecated.
Since autoboxing was introduced in JANINO, this feature is no longer necessary because you can use expression type `Object``.class`
`static final String`
`DEFAULT_CLASS_NAME`
The fully qualified name of the generated class, iff not reconfigured by `setClassName(String)`.
`static final Class<?>`
`DEFAULT_EXPRESSION_TYPE`
The type of all expressions that were not reconfigured with `setExpressionTypes(Class[])`.

## Method Summary

Modifier and Type
Method
Description
`<T> T`
`createFastEvaluator(Reader reader, Class<? extends T> interfaceToImplement, String... parameterNames)`
`<T> T`
`createFastEvaluator(String expression, Class<? extends T> interfaceToImplement, String... parameterNames)`
If the parameter and return types of the expression are known at compile time, then a "fast" expression evaluator can be instantiated through `createFastEvaluator(String, Class, String[])`.
`Object`
`evaluate()`
Shorthand for `evaluate``(new Object[0])`.
`Object`
`evaluate(int idx, Object[] arguments)`
Same as `evaluate(Object[])`, but for multiple expressions.
`Object`
`evaluate(Object[] arguments)`
Evaluates the expression with concrete parameter values.
`Class<?>`
`getClazz()`
`Class<?>`
`getDefaultExpressionType()`
`String[]`
`getDefaultImports()`
`Method`
`getMethod()`
`Method`
`getMethod(int idx)`
Same as `getMethod()`, but for multiple expressions.
`Method[]`
`getResult()`
`void`
`setClassName(String className)`
Sets the name of the generated class.
`void`
`setCompileErrorHandler(ErrorHandler compileErrorHandler)`
Installs an `ErrorHandler` which is invoked during compilation on each error.
`void`
`setDebuggingInformation(boolean debugSource, boolean debugLines, boolean debugVars)`
Determines what kind of debugging information is included in the generates classes.
`void`
`setDefaultExpressionType(Class<?> defaultExpressionType)`
Reconfigures the "default expression type"; if no expression type is configured for an expression, then, when cooking this `IExpressionEvaluator`, the "default expression type" is used for the expression
`void`
`setDefaultImports(String... defaultImports)`
"Default imports" add to the system import "java.lang", i.e.
`void`
`setExpressionType(Class<?> expressionType)`
Defines the type of the expression.
`void`
`setExpressionTypes(Class<?>[] expressionTypes)`
Configures the types of the expressions.
`void`
`setExtendedClass(Class<?> extendedType)`
Sets a particular superclass that the generated class will extend.
`void`
`setImplementedInterfaces(Class<?>[] implementedTypes)`
Configures the interfaces that the generated class implements.
`void`
`setMethodName(String methodName)`
Defines the name of the generated method.
`void`
`setMethodNames(String[] methodNames)`
Same as `setMethodName(String)`, but for multiple expressions.
`void`
`setOverrideMethod(boolean overrideMethod)`
Defines whether the generated method overrides a methods declared in a supertype.
`void`
`setOverrideMethod(boolean[] overrideMethod)`
Same as `setOverrideMethod(boolean)`, but for multiple expressions.
`void`
`setParameters(String[][] parameterNames, Class<?>[][] parameterTypes)`
Same as `setParameters(String[], Class[])`, but for multiple expressions.
`void`
`setParameters(String[] parameterNames, Class<?>[] parameterTypes)`
Defines the names and types of the parameters of the generated method.
`void`
`setParentClassLoader(ClassLoader parentClassLoader)`
The "parent class loader" is used to load referenced classes.
`void`
`setReturnType(Class<?> returnType)`
Deprecated.
Use `setExpressionType(Class)` instead
`void`
`setStaticMethod(boolean staticMethod)`
Defines whether the generated method should be STATIC or not.
`void`
`setStaticMethod(boolean[] staticMethod)`
Same as `setStaticMethod(boolean)`, but for multiple expressions.
`void`
`setThrownExceptions(Class<?>[] thrownExceptions)`
Defines the exceptions that the generated method may throw.
`void`
`setThrownExceptions(Class<?>[][] thrownExceptions)`
Same as `setThrownExceptions(Class[])`, but for multiple expressions.
`void`
`setWarningHandler(WarningHandler warningHandler)`
By default, warnings are discarded, but an application my install a custom `WarningHandler`.

### Methods inherited from interface org.codehaus.commons.compiler.ICookable

`cook, cook, cook, cook, cook, cook, cook, cook, cookFile, cookFile, cookFile, cookFile, getBytecodes, setSourceVersion, setTargetVersion`

### Methods inherited from interface org.codehaus.commons.compiler.IMultiCookable

`cook, cook, cook, cook, cook, cook, cook, cook, cookFiles, cookFiles, cookFiles, cookFiles`

## Field Details

### DEFAULT_CLASS_NAME

static final String DEFAULT_CLASS_NAME
The fully qualified name of the generated class, iff not reconfigured by `setClassName(String)`.

See Also:
  - Constant Field Values

### DEFAULT_EXPRESSION_TYPE

static final Class<?> DEFAULT_EXPRESSION_TYPE
The type of all expressions that were not reconfigured with `setExpressionTypes(Class[])`.

### ANY_TYPE

@Deprecated static final Class<?> ANY_TYPE
Deprecated.
Since autoboxing was introduced in JANINO, this feature is no longer necessary because you can use expression type `Object``.class`
Special value for `setExpressionType(Class)` that indicates that the expression may have any type.

## Method Details

### setParentClassLoader

void setParentClassLoader(@Nullable ClassLoader parentClassLoader)
The "parent class loader" is used to load referenced classes. Useful values are:

`System.getSystemClassLoader()` | The running JVM's class path
`Thread.currentThread().getContextClassLoader()` or `null` | The class loader effective for the invoking thread
`ClassLoaders.BOOTCLASSPATH_CLASS_LOADER` | The running JVM's boot class path

The parent class loader defaults to the current thread's context class loader.

### setDebuggingInformation

void setDebuggingInformation(boolean debugSource, boolean debugLines, boolean debugVars)
Determines what kind of debugging information is included in the generates classes. The default is typically "`-g:none`".

### setCompileErrorHandler

void setCompileErrorHandler(@Nullable ErrorHandler compileErrorHandler)
Installs an `ErrorHandler` which is invoked during compilation on each error. (By default, the compilation throws a `CompileException` on the first error and terminates.)

If the given `ErrorHandler` throws a `CompileException`, then the compilation terminates and the exception is propagated.

If the given `ErrorHandler` does not throw a `CompileException` but completes normally, then the compilation may or may not continue, depending on the error. Iff the compilation completes normally but errors were reported, then it will throw a `CompileException` indicating the number of errors.

In other words: The `ErrorHandler` may throw a `CompileException` or not, but the compilation will definitely throw a `CompileException` if one or more compile errors have occurred.

Parameters:
  `compileErrorHandler` - `null` to restore the default behavior (throwing a `CompileException`)

### setWarningHandler

void setWarningHandler(@Nullable WarningHandler warningHandler)
By default, warnings are discarded, but an application my install a custom `WarningHandler`.

Parameters:
  `warningHandler` - `null` to indicate that no warnings be issued

### evaluate

@Nullable Object evaluate() throws InvocationTargetException
Shorthand for `evaluate``(new Object[0])`.

Throws:
  `InvocationTargetException`

### evaluate

@Nullable Object evaluate(@Nullable Object[] arguments) throws InvocationTargetException
Evaluates the expression with concrete parameter values.

Each argument value must have the same type as specified through the "parameterTypes" parameter of `setParameters(String[], Class[])`.

Arguments of primitive type must passed with their wrapper class objects.

The object returned has the class as specified through `setExpressionType(Class)`.

This method is thread-safe.

`Null` arguments is equivalent with `new Object[0]`.

Notice: In version 3.1.8, the arguments parameter was changed from `Object[]` to `Object...`, which turned out to be a really bad decision because it caused a very ugly invocation ambiguity with `evaluate(int, Object[])`. Thus, with version 3.1.10, the parameter was changed back to `Object[]`.

Parameters:
  `arguments` - The actual parameter values
Throws:
  `InvocationTargetException`

### setDefaultExpressionType

void setDefaultExpressionType(Class<?> defaultExpressionType)
Reconfigures the "default expression type"; if no expression type is configured for an expression, then, when cooking this `IExpressionEvaluator`, the "default expression type" is used for the expression

### getDefaultExpressionType

Class<?> getDefaultExpressionType()

Returns:
  The currently configured "default expression type"
See Also:
  - `setDefaultExpressionType(Class)`

### setImplementedInterfaces

void setImplementedInterfaces(Class<?>[] implementedTypes)
Configures the interfaces that the generated class implements.

### setReturnType

@Deprecated void setReturnType(@Deprecated Class<?> returnType)
Deprecated.
Use `setExpressionType(Class)` instead

### setExpressionType

void setExpressionType(Class<?> expressionType)
Defines the type of the expression.

Defaults to `Object``.class`, which, thanks to autoboxing, allows for any expression type (including primitive types).

If `expressionType` is `void.class`, then the expression must be an invocation of a `void` method.

### setExpressionTypes

void setExpressionTypes(Class<?>[] expressionTypes)
Configures the types of the expressions.

Unless this method is called, all expressions have type `Object``.class`.

If any expression has type `void.class`, then it must be an invocation of a `void` method.

### setOverrideMethod

void setOverrideMethod(boolean overrideMethod)
Defines whether the generated method overrides a methods declared in a supertype.

### setOverrideMethod

void setOverrideMethod(boolean[] overrideMethod)
Same as `setOverrideMethod(boolean)`, but for multiple expressions.

### setParameters

void setParameters(String[] parameterNames, Class<?>[] parameterTypes)
Defines the names and types of the parameters of the generated method.

names`.length` and types`.length` must be equal. This invariant may be checked immediately, or later when the expression is cooked.

The parameters can be of primitive type, e.g. `double.class`.

The default is to have zero parameters.

### setParameters

void setParameters(String[][] parameterNames, Class<?>[][] parameterTypes)
Same as `setParameters(String[], Class[])`, but for multiple expressions.

### setClassName

void setClassName(String className)
Sets the name of the generated class. Defaults to `DEFAULT_CLASS_NAME`. In most cases, there is no need to set this name, because the generated class is loaded into its own `ClassLoader` where its name cannot collide with classes generated by other evaluators.

One reason to use this function is to have a class name in a non-default package, which can be relevant when types and members with DEFAULT accessibility are accessed.

### setExtendedClass

void setExtendedClass(Class<?> extendedType)
Sets a particular superclass that the generated class will extend. If extendedClass is `null`, the generated class will extend `Object`.

The usual reason to set a base class for an evaluator is that the generated class can directly access the superclass's (non-private) members.

### setDefaultImports

void setDefaultImports(String... defaultImports)
"Default imports" add to the system import "java.lang", i.e. the evaluator may refer to classes imported by default imports without having to explicitly declare IMPORT statements.

Notice that JDK 5 "static imports" are also supported, as shown here:

         sc.setDefaultImports(
             "java.util.Map",                          // Single type import
             "java.io.*",                              // Type-import-on-demand
             "static java.util.Collections.EMPTY_MAP", // Single static import
             "static java.util.Collections.*",         // Static-import-on-demand
         );

### getDefaultImports

String[] getDefaultImports()

Returns:
  The default imports that were previously configured with `setDefaultImports(String...)`

### setStaticMethod

void setStaticMethod(boolean staticMethod)
Defines whether the generated method should be STATIC or not. Defaults to `true`.

### setStaticMethod

void setStaticMethod(boolean[] staticMethod)
Same as `setStaticMethod(boolean)`, but for multiple expressions.

### setMethodName

void setMethodName(String methodName)
Defines the name of the generated method. Initially, the method name is "eval*".

Parameters:
  `methodName` - `null` means reset to default name
See Also:
  - `IScriptEvaluator.DEFAULT_METHOD_NAME`

### setMethodNames

void setMethodNames(String[] methodNames)
Same as `setMethodName(String)`, but for multiple expressions.

Define the names of the generated methods. By default the methods have distinct and implementation-specific names.

If two expressions have the same name, then they must have different parameter types (see `setParameters(String[][], Class[][])`).

### setThrownExceptions

void setThrownExceptions(Class<?>[] thrownExceptions)
Defines the exceptions that the generated method may throw.

### setThrownExceptions

void setThrownExceptions(Class<?>[][] thrownExceptions)
Same as `setThrownExceptions(Class[])`, but for multiple expressions.

### evaluate

@Nullable Object evaluate(int idx, @Nullable Object[] arguments) throws InvocationTargetException
Same as `evaluate(Object[])`, but for multiple expressions.

Notice: In version 3.1.8, the arguments parameter was changed from `Object[]` to `Object...`, which turned out to be a really bad decision because it caused a very ugly invocation ambiguity with `evaluate(int, Object[])`. Thus, with version 3.1.10, the parameter was changed back to `Object[]`.

Throws:
  `InvocationTargetException`

### createFastEvaluator

<T> T createFastEvaluator(String expression, Class<? extends T> interfaceToImplement, String... parameterNames) throws CompileException
If the parameter and return types of the expression are known at compile time, then a "fast" expression evaluator can be instantiated through `createFastEvaluator(String, Class, String[])`. Expression evaluation is faster than through `evaluate(Object[])`, because it is not done through reflection but through direct method invocation.

Example:

     public interface Foo {
         int bar(int a, int b);
     }
     ...
     ExpressionEvaluator ee = CompilerFactoryFactory.getDefaultCompilerFactory().newExpressionEvaluator();

     // Optionally configure the EE here...
     ee.setClassName("Bar");
     ee.setDefaultImports(new String[] { "java.util.*" });
     ee.setExtendedClass(SomeOtherClass.class);
     ee.setParentClassLoader(someClassLoader);

     // Optionally configure the EE here...
     Foo f = (Foo) ee.createFastEvaluator(
         "a + b",                    // expression to evaluate
         Foo.class,                  // interface that describes the expression's signature
         new String[] { "a", "b" }   // the parameters' names
     );
     System.out.println("1 + 2 = " + f.bar(1, 2)); // Evaluate the expression

All other configuration (implemented type, static method, return type, method name, parameter names and types, thrown exceptions) are predetermined by the interfaceToImplement.

Notice: The `interfaceToImplement` must be accessible by the compiled class, i.e. either be declared `public`, or with `protected` or default access in the package of the compiled class (see `setClassName(String)`.

Throws:
  `CompileException`

### createFastEvaluator

<T> T createFastEvaluator(Reader reader, Class<? extends T> interfaceToImplement, String... parameterNames) throws CompileException, IOException

Throws:
  `CompileException`
  `IOException`
See Also:
  - `createFastEvaluator(String, Class, String[])`

### getMethod

Method getMethod()

Returns:
  The generated and loaded `Method`
Throws:
  `IllegalStateException` - This IExpressionEvaluator is not yet cooked

### getMethod

Method getMethod(int idx)
Same as `getMethod()`, but for multiple expressions.

### getClazz

Class<?> getClazz()

Returns:
  The generated `Class`
Throws:
  `IllegalStateException` - This `IClassBodyEvaluator` is not yet cooked

### getResult

Method[] getResult()

Returns:
  The generated and loaded methods that implement the cooked expressions
Throws:
  `IllegalStateException` - This `IScriptEvaluator` is not yet cooked