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)
           
 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 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)
           
 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)
          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 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
 String getSuperClassName()
          Get the name of the Java class containing the compiled query
 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(int fingerprint)
          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

getSuperClassName

public String getSuperClassName()
Get the name of the Java class containing the compiled query

Returns:
the fully qualified class name, for example "com.saxonica.compquery.AccountsQuery"

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.


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


getXPathVariableName

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


assign

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


generateLocalVariableDeclaration

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


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


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


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 XPathContext

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)
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.
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

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


getMethodName

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

Parameters:
fn -
Returns:
the name of the Java method

getFunctionEvaluationMode

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


compileMainExpression

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

Parameters:
exp -

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.


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 -
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)

compileItemType

public String compileItemType(ItemType type)

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(int fingerprint)
Compile a function that implements a given key definition

Parameters:
fingerprint - the fingerprint of the key definition

compileKeyDefinitionSetters

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


compileKeyDefinitionClasses

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


compileNamespaceContext

public String compileNamespaceContext(NamespaceResolver resolver)
Compile a namespace context


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.