com.saxonica.codegen
Class CompilerService

java.lang.Object
  extended by com.saxonica.codegen.CompilerService

public class CompilerService
extends Object

The class contains the generic logic for generating Java code to evaluate an XQuery expression.

The class contains methods to generate the boilerplate code of the Java module, and many service methods used as callbacks by the specific compiler classes for each kind of expression. It also handles code layout, detecting curly braces in the generated code and using them to trigger indentation changes.


Field Summary
static int RETURN
           
 
Constructor Summary
CompilerService()
           
 
Method Summary
 void assign(String variable, String expression)
          Generate an assignment to a variable
 String cast(String variable, Class target)
          Generate a Java cast unless it is known to be unnecessary.
 String collationVariable(String uri)
          Given a URI representing a collation, register the collation and return the name of a Java variable that can be used to reference the collation in the generated Java code
 void compileAsLoop(Expression exp, LoopAction action)
          Compile Java code whose effect is to loop over the results of an expression, calling the supplied callback function to generate the code that processes each item in the sequence.
 String compileAtomicComparer(AtomicComparer comp)
          Generate code to declare an AtomicComparer for a collation known statically
 void compileFunction(XQueryFunction fn)
          Compile an XQuery function
 void compileGlobalVariable(GlobalVariable decl)
          Compile code to declare and initialize a global variable, that is, a variable declared in the query prolog
 String compileItemType(ItemType type)
          Compile the declaration of an XPath item typs
 void compileKeyDefinitionClasses()
          Compile class definitions corresponding to all the requested key definitions
 void compileKeyDefinitionSetters()
          Compile initialization code to establish the key definitions
 void compileMainExpression(Expression exp)
          Compile the main expression in the query module
 String compileNamespaceContext(NamespaceResolver resolver)
          Compile a namespace context
 String compileNodeTest(NodeTest test)
          Compile code for a node test used in a path expression
 void compilePush(Expression exp)
          Compile Java code whose effect is to send the result of the given expression to the current output Receiver
 String compileRegularExpression(String translated, int flagBits)
          Generate an instance variable representing a compiled regular expression, and return its name
 String compileStructuredQName(StructuredQName qName)
          Compile a StructuredQName
 String compileToCharSequence(Expression exp)
          Compile Java code whose effect is to compute the string value of the expression; the generated code returns a CharSequence
 String compileToEffectiveBooleanValue(Expression exp, ReturnAction action)
          Compile Java code whose effect is to compute the effective boolean value of the expression; the generated code returns a boolean
 String compileToItem(Expression exp)
          Compile Java code whose effect is to evaluate the expression, which must have a cardinality of zero-or-one; the generated code returns either an Item or null (representing an empty sequence)
 String compileToIterator(Expression exp)
          Compile Java code whose effect is to create an iterator over the result of the given expression
 String compileToValueRepresentation(Expression exp)
          Compile an expression to place its results in an object of class ValueRepresentation
 String declare(Class declaredType, String name, String initializer, boolean isFinal)
          Declare a variable locally within a method.
 String declareNameCode(int nc)
          Declare a Java variable holding an integer namecode representing a QName in the run-time name pool
 String declareNamespaceCode(int nsc)
          Declare a Java variable holding an integer namespace code representing a prefix=uri binding in the run-time name pool
 void emit(String s)
          Output a line of Java code.
 void emitComment(String s)
          Output a Java comment
 void emitDynamicError(String message, String code)
          Output Java code to signal a dynamic error.
 String emitInstanceVariable(Class type, String name, String initializer, boolean isStatic, boolean isFinal, String messageIfNull, String errorCodeIfNull)
          Generate a declaration of a non-local variable.
 void endMethod()
          Register the end of a "method"
 void epilogue()
          Output the epilogue, that is, the material at the end of the Java code module
 String generateLocalVariableDeclaration(Class declaredType, String name, String initializer, boolean isFinal)
          Generate a local variable declaration
 String getClassName(Class target)
          Get the name of a Java class for use in the generated code.
 Configuration getConfiguration()
          Get the Saxon configuration
 String getContextItemVariableName()
          Get the name of the Java variable currently bound to the context item
 String getContextPositionVariableName()
          Get the name of the Java variable currently bound to the context position
 String getContextSizeVariableName()
          Get the name of the Java variable currently bound to the context size (last())
 String getContextVariableName()
          Get the name of the Java variable currently bound to the dynamic XPathContext object
 ExpressionCompiler getExpressionCompiler(Expression exp)
          Get a compiler for a particular kind of expression.
 int getFunctionEvaluationMode(UserFunction function)
          Determine what mode a function should be evaluated in: push, evaluateItem, or ValueRepresentation
 Class getJavaClassForFunctionParameter(UserFunction fn, int i)
          Get the Java class to use for a given function argument
 String getMethodName(UserFunction fn)
          Get the Java method name to use for a given user-defined function
 NamePool getNamePool()
          Get the name pool used by the Saxon configuration
 String getOutputterVariableName()
          Get the name of the Java variable currently bound to current output destination
 TypeHierarchy getTypeHierarchy()
          Get the TypeHierarchy which holds a cache of type information relevant to the query being compiled
 int getUniqueNumber()
          Allocate a unique number within the module, for use in variable names
 ValueCompiler getValueCompiler(Value val)
          Get a ValueCompiler for a particular kind of Value (usually an AtomicValue) appearing as a literal in a query
 String getXPathVariableName(int slotNumber)
          Get the name of the Java variable used to represent the XPath variable occupying a given slot
 void indent()
          Add indentation to the output Java code.
 boolean isInServletMode()
          Test whether compilation is in servlet mode
 boolean isInstance(String variable, Class target)
          Test whether a given variable is known to be an instance of a particular Java class
 boolean isXSLT()
          Determine whether we are compiling XSLT rather than XQuery
static String javaEscape(CharSequence in)
          Generate a Java string literal with appropriate escaping of special characters
 void makeKeyDefinitionFunction(StructuredQName keyName)
          Compile a function that implements a given key definition
 String makeValidJavaName(String name)
          Given a candidate Java name, make it into a valid Java name
 void outdent()
          Reduce the indentation level of the output Java code.
 void popContextItemVariable()
          Deregister the variable name currently used for the context item, reverting to the previously used variable name
 void popContextPositionVariable()
          Deregister the variable name currently used for the context position, reverting to the previously used variable name
 void popContextSizeVariable()
          Deregister the variable name currently used for the context size, reverting to the previously used variable name
 void popContextVariable()
          Deregister the variable name currently used for the dynamic XPathContext object, reverting to the previously used variable name
 void popOutputterVariable()
          Deregister the variable name currently used for the current output destination, reverting to the previously used variable name
 void prologue(boolean mainModule)
          Output the prologue, that is, the material at the start of the Java code module
 void pushContextItemVariable(String variableName)
          Register the variable name currently used for the context item, adding it to a stack
 void pushContextPositionVariable(String variableName)
          Register the variable name currently used for the context position, adding it to a stack
 void pushContextSizeVariable(String variableName)
          Register the variable name currently used for the context size, adding it to a stack
 void pushContextVariable(String variableName)
          Register the variable name currently used for the dynamic XPathContext object, adding it to a stack
 void pushOutputterVariable(String variableName)
          Register the variable name currently used for the current output destination, adding it to a stack
 void registerLocalVariable(Class declaredType, String name)
          Register a local variable that has been declared (e.g.
 void setBaseURI(String baseURI)
          Set the base URI of the query to be compiled
 void setClassName(String packageName, String className)
          Set the package name and class name of the generated Java code
 void setConfiguration(Configuration config)
          Set the Saxon configuration used by this query compiler
 void setExecutable(Executable exec)
          Set the Saxon executable containing the query to be compiled
 void setPrintWriter(PrintWriter writer)
          Set the destination for the generated Java code
 void setServletMode(boolean onOrOff)
          Set servlet mode for compilation
 void setSuperClassName(String className)
          Set the name of the Java class to be used as the superclass the compiled query.
 void setXPathVariableName(int slotNumber, String name)
          Register the name of the Java variable used to represent the XPath variable occupying a given slot
 void startMethod()
          Register the start of a new "method" (also covers similar top-level constructs such as static initializers)
 
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

RETURN

public static final int RETURN
See Also:
Constant Field Values
Constructor Detail

CompilerService

public CompilerService()
Method Detail

setServletMode

public void setServletMode(boolean onOrOff)
Set servlet mode for compilation

Parameters:
onOrOff - true to set servlet mode on, false to set it off

isInServletMode

public boolean isInServletMode()
Test whether compilation is in servlet mode

Returns:
true if servlet mode is on, false if it is off

setSuperClassName

public void setSuperClassName(String className)
Set the name of the Java class to be used as the superclass the compiled query. This can be a user-written subclass of CompiledUserQuery or CompiledQueryServlet, or potentially any other class that contains the methods called by the generated Java code.

Parameters:
className - the fully qualified name of the superclass

getExpressionCompiler

public ExpressionCompiler getExpressionCompiler(Expression exp)
Get a compiler for a particular kind of expression. This is obtained by reference to the ExpressionClassMapper

Parameters:
exp - the expression to compile
Returns:
the expression compiler for that kind of expression

getValueCompiler

public ValueCompiler getValueCompiler(Value val)
Get a ValueCompiler for a particular kind of Value (usually an AtomicValue) appearing as a literal in a query

Parameters:
val - the value to be compiled
Returns:
a Java representation of the value

setConfiguration

public void setConfiguration(Configuration config)
Set the Saxon configuration used by this query compiler

Parameters:
config - the Saxon configuration

setExecutable

public void setExecutable(Executable exec)
Set the Saxon executable containing the query to be compiled

Parameters:
exec - the Saxon Executable

getConfiguration

public Configuration getConfiguration()
Get the Saxon configuration

Returns:
the Saxon configuration

getNamePool

public NamePool getNamePool()
Get the name pool used by the Saxon configuration

Returns:
the name pool

getTypeHierarchy

public TypeHierarchy getTypeHierarchy()
Get the TypeHierarchy which holds a cache of type information relevant to the query being compiled

Returns:
the TypeHierarchy

isXSLT

public boolean isXSLT()
Determine whether we are compiling XSLT rather than XQuery

Returns:
false

setPrintWriter

public void setPrintWriter(PrintWriter writer)
Set the destination for the generated Java code

Parameters:
writer - a PrintWriter with which the generated code should be written

setClassName

public void setClassName(String packageName,
                         String className)
Set the package name and class name of the generated Java code

Parameters:
packageName - the hierarchic package name
className - the class name, excluding any package name

setBaseURI

public void setBaseURI(String baseURI)
Set the base URI of the query to be compiled

Parameters:
baseURI - the static base URI of the query

getUniqueNumber

public int getUniqueNumber()
Allocate a unique number within the module, for use in variable names

Returns:
a unique number

startMethod

public void startMethod()
Register the start of a new "method" (also covers similar top-level constructs such as static initializers)


endMethod

public void endMethod()
Register the end of a "method"


declare

public String declare(Class declaredType,
                      String name,
                      String initializer,
                      boolean isFinal)
Declare a variable locally within a method. If the declaration is redundant, the call returns the string name of the variable which should be used in place of the declared variable.

Parameters:
declaredType - the Java class of the variable to be declared
name - the name of the variable to be declared
initializer - Java expression to provide an initial value
isFinal - true if the variable should be declared as final
Returns:
the name of the declared variable

setXPathVariableName

public void setXPathVariableName(int slotNumber,
                                 String name)
Register the name of the Java variable used to represent the XPath variable occupying a given slot

Parameters:
slotNumber - the slot allocated to the XPath variable on the XPath execution stack
name - the name of the Java variable used to represent this XPath variable

getXPathVariableName

public String getXPathVariableName(int slotNumber)
Get the name of the Java variable used to represent the XPath variable occupying a given slot

Parameters:
slotNumber - the slot allocated to the variable on the XPath execution stack
Returns:
the name of the Java variable representing this XPath variable

assign

public void assign(String variable,
                   String expression)
Generate an assignment to a variable

Parameters:
variable - the name of the variable
expression - the Java expression to appear on the rhs of the assignment

generateLocalVariableDeclaration

public String generateLocalVariableDeclaration(Class declaredType,
                                               String name,
                                               String initializer,
                                               boolean isFinal)
Generate a local variable declaration

Parameters:
declaredType - the Java class of the variable
name - the proposed Java name for the variable
initializer - the expression used to initialize the variable
isFinal - true if the variable is to be declared as "final".
Returns:
the name of the Java variable actually used

registerLocalVariable

public void registerLocalVariable(Class declaredType,
                                  String name)
Register a local variable that has been declared (e.g. a function parameter) without emitting any code

Parameters:
declaredType - the Java class of the variable
name - the Java name of the variable

cast

public String cast(String variable,
                   Class target)
Generate a Java cast unless it is known to be unnecessary.

Parameters:
variable - the name of the variable that possibly needs to be cast
target - the required type for the expression where the variable is being used
Returns:
either the variable name on its own, if no cast is required, or a string in the form "((class)variable)" if casting is needed.

isInstance

public boolean isInstance(String variable,
                          Class target)
Test whether a given variable is known to be an instance of a particular Java class

Parameters:
variable - the name of the Java variable
target - the Java class
Returns:
true if it is known that this variable is an instance of this class

indent

public void indent()
Add indentation to the output Java code. This allows manual indentation, which is not normally necessary, because code is indented automatically when curly braces are encountered


outdent

public void outdent()
Reduce the indentation level of the output Java code. This allows manual indentation, which is not normally necessary, because code is indented automatically when curly braces are encountered


pushContextVariable

public void pushContextVariable(String variableName)
Register the variable name currently used for the dynamic XPathContext object, adding it to a stack

Parameters:
variableName - the name of the variable currently bound to the XPathContext

popContextVariable

public void popContextVariable()
Deregister the variable name currently used for the dynamic XPathContext object, reverting to the previously used variable name


pushContextItemVariable

public void pushContextItemVariable(String variableName)
Register the variable name currently used for the context item, adding it to a stack

Parameters:
variableName - the name of the variable currently bound to the XPathContext. By convention, if the variable name begins with "node" then we can rely on the fact that the context item exists and is a node (though it may need to be cast)

popContextItemVariable

public void popContextItemVariable()
Deregister the variable name currently used for the context item, reverting to the previously used variable name


pushContextPositionVariable

public void pushContextPositionVariable(String variableName)
Register the variable name currently used for the context position, adding it to a stack

Parameters:
variableName - the name of the variable currently bound to the context position. It is normally a boxed value (IntegerValue) unless the name ends with ".position()", in which case it is unboxed.

popContextPositionVariable

public void popContextPositionVariable()
Deregister the variable name currently used for the context position, reverting to the previously used variable name


pushContextSizeVariable

public void pushContextSizeVariable(String variableName)
Register the variable name currently used for the context size, adding it to a stack

Parameters:
variableName - the name of the variable currently bound to the XPathContext

popContextSizeVariable

public void popContextSizeVariable()
Deregister the variable name currently used for the context size, reverting to the previously used variable name


getContextVariableName

public String getContextVariableName()
Get the name of the Java variable currently bound to the dynamic XPathContext object

Returns:
the Java variable name

getContextItemVariableName

public String getContextItemVariableName()
Get the name of the Java variable currently bound to the context item

Returns:
the Java variable name

getContextPositionVariableName

public String getContextPositionVariableName()
Get the name of the Java variable currently bound to the context position

Returns:
the Java variable name

getContextSizeVariableName

public String getContextSizeVariableName()
Get the name of the Java variable currently bound to the context size (last())

Returns:
the Java variable name

pushOutputterVariable

public void pushOutputterVariable(String variableName)
Register the variable name currently used for the current output destination, adding it to a stack

Parameters:
variableName - the name of the variable currently bound to the XPathContext

popOutputterVariable

public void popOutputterVariable()
Deregister the variable name currently used for the current output destination, reverting to the previously used variable name


getOutputterVariableName

public String getOutputterVariableName()
Get the name of the Java variable currently bound to current output destination

Returns:
the Java variable name

emit

public void emit(String s)
Output a line of Java code. Indentation happens automatically based on recognition of "{" and "}" braces with the code.

Parameters:
s - the line of Java code

emitComment

public void emitComment(String s)
Output a Java comment

Parameters:
s - the text of the comment

emitDynamicError

public void emitDynamicError(String message,
                             String code)
Output Java code to signal a dynamic error. This can currently only handle cases where the error message is known at code generation time.

Parameters:
message - the error message
code - the error code

declareNameCode

public String declareNameCode(int nc)
Declare a Java variable holding an integer namecode representing a QName in the run-time name pool

Parameters:
nc - the compile time name code of the QName. This will not necessarily be the same as the run-time name code.
Returns:
the name of the variable that will hold the name code at runtime

declareNamespaceCode

public String declareNamespaceCode(int nsc)
Declare a Java variable holding an integer namespace code representing a prefix=uri binding in the run-time name pool

Parameters:
nsc - the compile time namespace code. This will not necessarily be the same as the run-time namespace code.
Returns:
the name of the variable that will hold the name code at runtime

makeValidJavaName

public String makeValidJavaName(String name)
Given a candidate Java name, make it into a valid Java name

Parameters:
name - a candidate Java name
Returns:
a valid Java name

emitInstanceVariable

public String emitInstanceVariable(Class type,
                                   String name,
                                   String initializer,
                                   boolean isStatic,
                                   boolean isFinal,
                                   String messageIfNull,
                                   String errorCodeIfNull)
Generate a declaration of a non-local variable. If the variable is static and no name is assigned, the declaration is pooled, to avoid multiple declarations of the same constants.

Parameters:
type - The Java class of the variable
name - The name to be given to the variable. If null is supplied, a name will be allocated and returned as the result of the function
initializer - The initial value of the expression
isStatic - True if the declaration is to be static.
isFinal - True if the declaration is to be final. This implies that the initializer can be output directly, it doesn't require a separate assignment during the initialization procedure.
messageIfNull - Error message to be produced at run-time if the value is null (if any)
errorCodeIfNull - Error code to be produced at run-time if the value is null (if any)
Returns:
the name assigned to the variable. If a name was explicitly requested, the request will be honoured.

collationVariable

public String collationVariable(String uri)
Given a URI representing a collation, register the collation and return the name of a Java variable that can be used to reference the collation in the generated Java code

Parameters:
uri - a URI representing a collation
Returns:
the name of a Java variable holding the collation object at run-time

prologue

public void prologue(boolean mainModule)
Output the prologue, that is, the material at the start of the Java code module

Parameters:
mainModule - true if this is the main module

compileGlobalVariable

public void compileGlobalVariable(GlobalVariable decl)
Compile code to declare and initialize a global variable, that is, a variable declared in the query prolog

Parameters:
decl - the global variable declaration to be compiled

getClassName

public String getClassName(Class target)
Get the name of a Java class for use in the generated code.

Parameters:
target - the class whose name is required
Returns:
the name of the class, abbreviated if possible

compileFunction

public void compileFunction(XQueryFunction fn)
Compile an XQuery function

Parameters:
fn - the function to be compiled

getJavaClassForFunctionParameter

public Class getJavaClassForFunctionParameter(UserFunction fn,
                                              int i)
Get the Java class to use for a given function argument

Parameters:
fn - the user-defined function
i - index of the relevant argument
Returns:
the Java class used to represent the value of this argument

getMethodName

public String getMethodName(UserFunction fn)
Get the Java method name to use for a given user-defined function

Parameters:
fn - the user-defined function
Returns:
the name of the Java method containing the code of this function

getFunctionEvaluationMode

public int getFunctionEvaluationMode(UserFunction function)
Determine what mode a function should be evaluated in: push, evaluateItem, or ValueRepresentation

Parameters:
function - the user-defined function
Returns:
the evaluation mode for the function

compileMainExpression

public void compileMainExpression(Expression exp)
Compile the main expression in the query module

Parameters:
exp - the main expression

epilogue

public void epilogue()
Output the epilogue, that is, the material at the end of the Java code module


compilePush

public void compilePush(Expression exp)
Compile Java code whose effect is to send the result of the given expression to the current output Receiver

Parameters:
exp - the expression to be compiled

compileToIterator

public String compileToIterator(Expression exp)
Compile Java code whose effect is to create an iterator over the result of the given expression

Parameters:
exp - the expression to be compiled
Returns:
the name of a variable to which the resulting SequenceIterator will be writte.

compileAsLoop

public void compileAsLoop(Expression exp,
                          LoopAction action)
Compile Java code whose effect is to loop over the results of an expression, calling the supplied callback function to generate the code that processes each item in the sequence.

Parameters:
exp - the expression being compiled
action - callback action to generate code for the body of the loop

compileToItem

public String compileToItem(Expression exp)
Compile Java code whose effect is to evaluate the expression, which must have a cardinality of zero-or-one; the generated code returns either an Item or null (representing an empty sequence)

Parameters:
exp - The expression to be compiled, which must have a static cardinality of zero or one.
Returns:
the name of a variable to which the resulting Item is assigned.

compileToEffectiveBooleanValue

public String compileToEffectiveBooleanValue(Expression exp,
                                             ReturnAction action)
Compile Java code whose effect is to compute the effective boolean value of the expression; the generated code returns a boolean

Parameters:
exp - The expression to be compiled
action - Represents the way in which the result of the boolean expression is to be returned
Returns:
the name of a variable to which the resulting boolean is assigned, or a Java expression that can be used in a place where a variable reference is allowed.

compileToCharSequence

public String compileToCharSequence(Expression exp)
Compile Java code whose effect is to compute the string value of the expression; the generated code returns a CharSequence

Parameters:
exp - The expression to be compiled
Returns:
the name of a variable to which the resulting CharSequence is assigned, or a Java expression that can be used in a place where a variable reference of type CharSequence is allowed.

compileToValueRepresentation

public String compileToValueRepresentation(Expression exp)
Compile an expression to place its results in an object of class ValueRepresentation

Parameters:
exp - the expression to be compiled
Returns:
the name of the Java variable that will hold the ValueRepresentation

compileItemType

public String compileItemType(ItemType type)
Compile the declaration of an XPath item typs

Parameters:
type - the item type
Returns:
the name of the Java variable that will contain this item type definition

compileNodeTest

public String compileNodeTest(NodeTest test)
Compile code for a node test used in a path expression

Parameters:
test - the node test
Returns:
the name of a variable that will be bound to the node test

compileRegularExpression

public String compileRegularExpression(String translated,
                                       int flagBits)
Generate an instance variable representing a compiled regular expression, and return its name

Parameters:
translated - the regular expression, translated to Java regex syntax
flagBits - the flag bits as used by the Java regex engine
Returns:
the name of the generated variable

compileAtomicComparer

public String compileAtomicComparer(AtomicComparer comp)
Generate code to declare an AtomicComparer for a collation known statically

Parameters:
comp - the AtomicComparer to be reproduced in the compiled code
Returns:
a Java expression whose runtime value is the required AtomicComparer

makeKeyDefinitionFunction

public void makeKeyDefinitionFunction(StructuredQName keyName)
Compile a function that implements a given key definition

Parameters:
keyName - the QName of the key definition

compileKeyDefinitionSetters

public void compileKeyDefinitionSetters()
Compile initialization code to establish the key definitions


compileStructuredQName

public String compileStructuredQName(StructuredQName qName)
Compile a StructuredQName

Parameters:
qName - the StructuredQName
Returns:
the name of the Java variable that will hold the StructuredQName

compileKeyDefinitionClasses

public void compileKeyDefinitionClasses()
Compile class definitions corresponding to all the requested key definitions


compileNamespaceContext

public String compileNamespaceContext(NamespaceResolver resolver)
Compile a namespace context

Parameters:
resolver - a NamespaceResolver representing a namespace context
Returns:
the name of a Java variable

javaEscape

public static String javaEscape(CharSequence in)
Generate a Java string literal with appropriate escaping of special characters

Parameters:
in - the value of the string literal
Returns:
a Java string literal, with enclosing quotations marks, and with special characters escaped using the Java conventions.


Copyright (C) Michael H. Kay. All rights reserved.