Example #1
0
 /*@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;
 }
Example #2
0
  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);
    }
  }
Example #3
0
 /**
  * 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();
     }
   }
 }
Example #4
0
 public void checkArguments(/*@NotNull*/ ExpressionVisitor visitor) throws XPathException {
   if (expressionBaseURI == null) {
     super.checkArguments(visitor);
     expressionBaseURI = visitor.getStaticContext().getBaseURI();
   }
 }
Example #5
0
 /*@NotNull*/
 public Expression simplify(ExpressionVisitor visitor) throws XPathException {
   sequence = visitor.simplify(sequence);
   action = visitor.simplify(action);
   return this;
 }
Example #6
0
  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());
    }
  }