/*@NotNull*/ public Expression optimize( /*@NotNull*/ ExpressionVisitor visitor, ExpressionVisitor.ContextItemType contextItemType) throws XPathException { Expression e2 = super.optimize(visitor, contextItemType); if (e2 != this) { return e2; } // See if we can deduce the answer from the cardinality int c = argument[0].getCardinality(); if (c == StaticProperty.ALLOWS_ONE_OR_MORE) { return new Literal(BooleanValue.FALSE); } else if (c == StaticProperty.ALLOWS_ZERO) { return new Literal(BooleanValue.TRUE); } // Rewrite // empty(A|B) => empty(A) and empty(B) if (argument[0] instanceof VennExpression) { VennExpression v = (VennExpression) argument[0]; if (v.getOperator() == Token.UNION && !visitor.isOptimizeForStreaming()) { FunctionCall e0 = SystemFunction.makeSystemFunction("empty", new Expression[] {v.getOperands()[0]}); FunctionCall e1 = SystemFunction.makeSystemFunction("empty", new Expression[] {v.getOperands()[1]}); return new AndExpression(e0, e1).optimize(visitor, contextItemType); } } return this; }
public void typeCheckBody() throws XPathException { Expression exp = compiledFunction.getBody(); Expression exp2 = exp; ExpressionVisitor visitor = makeExpressionVisitor(); try { // We've already done the typecheck of each XPath expression, but it's worth doing again at // this // level because we have more information now. exp2 = visitor.typeCheck(exp, null); if (resultType != null) { RoleLocator role = new RoleLocator(RoleLocator.FUNCTION_RESULT, functionName, 0); role.setErrorCode("XTTE0780"); exp2 = TypeChecker.staticTypeCheck(exp2, resultType, false, role, visitor); } } catch (XPathException err) { err.maybeSetLocation(this); compileError(err); } if (exp2 != exp) { compiledFunction.setBody(exp2); } }
/** * Refine the type information associated with this variable declaration. This is useful when the * type of the variable has not been explicitly declared (which is common); the variable then * takes a static type based on the type of the expression to which it is bound. The effect of * this call is to update the static expression type for all references to this variable. * * @param type the inferred item type of the expression to which the variable is bound * @param cardinality the inferred cardinality of the expression to which the variable is bound * @param constantValue the constant value to which the variable is bound (null if there is no * constant value) * @param properties other static properties of the expression to which the variable is bound * @param visitor an expression visitor to provide context information * @param currentExpression the expression that binds the variable */ public void refineTypeInformation( ItemType type, int cardinality, Value constantValue, int properties, ExpressionVisitor visitor, Assignation currentExpression) { List references = new ArrayList(); ExpressionTool.gatherVariableReferences(currentExpression.getAction(), this, references); for (Iterator iter = references.iterator(); iter.hasNext(); ) { BindingReference ref = (BindingReference) iter.next(); if (ref instanceof VariableReference) { ((VariableReference) ref) .refineVariableType(type, cardinality, constantValue, properties, visitor); visitor.resetStaticProperties(); } } }
public void checkArguments(/*@NotNull*/ ExpressionVisitor visitor) throws XPathException { if (expressionBaseURI == null) { super.checkArguments(visitor); expressionBaseURI = visitor.getStaticContext().getBaseURI(); } }
/*@NotNull*/ public Expression simplify(ExpressionVisitor visitor) throws XPathException { sequence = visitor.simplify(sequence); action = visitor.simplify(action); return this; }
public void optimize(Declaration declaration) throws XPathException { Expression exp = compiledFunction.getBody(); ExpressionVisitor visitor = makeExpressionVisitor(); Expression exp2 = exp; Optimizer opt = getConfiguration().obtainOptimizer(); try { if (opt.getOptimizationLevel() != Optimizer.NO_OPTIMIZATION) { exp2 = exp.optimize(visitor, null); } } catch (XPathException err) { err.maybeSetLocation(this); compileError(err); } // Try to extract new global variables from the body of the function if (opt.getOptimizationLevel() != Optimizer.NO_OPTIMIZATION) { Expression exp3 = opt.promoteExpressionsToGlobal(exp2, visitor); if (exp3 != null) { exp2 = visitor.optimize(exp3, null); } } // Add trace wrapper code if required exp2 = makeTraceInstruction(this, exp2); allocateSlots(exp2); if (exp2 != exp) { compiledFunction.setBody(exp2); } int tailCalls = ExpressionTool.markTailFunctionCalls(exp2, getObjectName(), getNumberOfArguments()); if (tailCalls != 0) { compiledFunction.setTailRecursive(tailCalls > 0, tailCalls > 1); compiledFunction.setBody(new TailCallLoop(compiledFunction)); } // Generate byte code if appropriate if (getConfiguration().isGenerateByteCode(Configuration.XSLT)) { try { Expression cbody = opt.compileToByteCode( compiledFunction.getBody(), nameAtt, Expression.PROCESS_METHOD | Expression.ITERATE_METHOD); if (cbody != null) { compiledFunction.setBody(cbody); } } catch (Exception e) { System.err.println("Failed while compiling function " + nameAtt); e.printStackTrace(); throw new XPathException(e); } } compiledFunction.computeEvaluationMode(); if (isExplaining()) { exp2.explain(getConfiguration().getStandardErrorOutput()); } }