Beispiel #1
0
 /*  63:    */
 /*  64:    */ public Type typeCheck(SymbolTable stable) /*  65:    */ throws TypeCheckError
       /*  66:    */ {
   /*  67:120 */ if (this._type != null) {
     /*  68:120 */ return this._type;
     /*  69:    */ }
   /*  70:123 */ if (this._variable.isLocal())
   /*  71:    */ {
     /*  72:124 */ SyntaxTreeNode node = getParent();
     /*  73:    */ do
     /*  74:    */ {
       /*  75:126 */ if ((node instanceof Closure))
       /*  76:    */ {
         /*  77:127 */ this._closure = ((Closure) node);
         /*  78:128 */ break;
         /*  79:    */ }
       /*  80:130 */ if ((node instanceof TopLevelElement)) {
         /*  81:    */ break;
         /*  82:    */ }
       /*  83:133 */ node = node.getParent();
       /*  84:134 */ } while (node != null);
     /*  85:136 */ if (this._closure != null) {
       /*  86:137 */ this._closure.addVariable(this);
       /*  87:    */ }
     /*  88:    */ }
   /*  89:142 */ this._type = this._variable.getType();
   /*  90:146 */ if (this._type == null)
   /*  91:    */ {
     /*  92:147 */ this._variable.typeCheck(stable);
     /*  93:148 */ this._type = this._variable.getType();
     /*  94:    */ }
   /*  95:152 */ addParentDependency();
   /*  96:    */
   /*  97:    */
   /*  98:155 */ return this._type;
   /*  99:    */ }
Beispiel #2
0
  /**
   * Type check a predicate expression. If the type of the expression is number convert it to
   * boolean by adding a comparison with position(). Note that if the expression is a parameter, we
   * cannot distinguish at compile time if its type is number or not. Hence, expressions of
   * reference type are always converted to booleans.
   *
   * <p>This method may be called twice, before and after calling <code>dontOptimize()</code>. If
   * so, the second time it should honor the new value of <code>_canOptimize</code>.
   */
  public Type typeCheck(SymbolTable stable) throws TypeCheckError {
    Type texp = _exp.typeCheck(stable);

    // We need explicit type information for reference types - no good!
    if (texp instanceof ReferenceType) {
      _exp = new CastExpr(_exp, texp = Type.Real);
    }

    // A result tree fragment should not be cast directly to a number type,
    // but rather to a boolean value, and then to a numer (0 or 1).
    // Ref. section 11.2 of the XSLT 1.0 spec
    if (texp instanceof ResultTreeType) {
      _exp = new CastExpr(_exp, Type.Boolean);
      _exp = new CastExpr(_exp, Type.Real);
      texp = _exp.typeCheck(stable);
    }

    // Numerical types will be converted to a position filter
    if (texp instanceof NumberType) {
      // Cast any numerical types to an integer
      if (texp instanceof IntType == false) {
        _exp = new CastExpr(_exp, Type.Int);
      }

      if (_canOptimize) {
        // Nth position optimization. Expression must not depend on context
        _nthPositionFilter = !_exp.hasLastCall() && !_exp.hasPositionCall();

        // _nthDescendant optimization - only if _nthPositionFilter is on
        if (_nthPositionFilter) {
          SyntaxTreeNode parent = getParent();
          _nthDescendant =
              (parent instanceof Step) && (parent.getParent() instanceof AbsoluteLocationPath);
          return _type = Type.NodeSet;
        }
      }

      // Reset optimization flags
      _nthPositionFilter = _nthDescendant = false;

      // Otherwise, expand [e] to [position() = e]
      final QName position = getParser().getQNameIgnoreDefaultNs("position");
      final PositionCall positionCall = new PositionCall(position);
      positionCall.setParser(getParser());
      positionCall.setParent(this);

      _exp = new EqualityExpr(Operators.EQ, positionCall, _exp);
      if (_exp.typeCheck(stable) != Type.Boolean) {
        _exp = new CastExpr(_exp, Type.Boolean);
      }
      return _type = Type.Boolean;
    } else {
      // All other types will be handled as boolean values
      if (texp instanceof BooleanType == false) {
        _exp = new CastExpr(_exp, Type.Boolean);
      }
      return _type = Type.Boolean;
    }
  }
Beispiel #3
0
 /** Returns a reference to its parent closure or null if outermost. */
 public Closure getParentClosure() {
   if (_parentClosure == null) {
     SyntaxTreeNode node = getParent();
     do {
       if (node instanceof Closure) {
         _parentClosure = (Closure) node;
         break;
       }
       if (node instanceof TopLevelElement) {
         break; // way up in the tree
       }
       node = node.getParent();
     } while (node != null);
   }
   return _parentClosure;
 }
Beispiel #4
0
 /*  27:    */
 /*  28:    */ public void addParentDependency() /*  29:    */ {
   /*  30: 73 */ SyntaxTreeNode node = this;
   /*  31: 74 */ while ((node != null) && (!(node instanceof TopLevelElement))) {
     /*  32: 75 */ node = node.getParent();
     /*  33:    */ }
   /*  34: 78 */ TopLevelElement parent = (TopLevelElement) node;
   /*  35: 79 */ if (parent != null)
   /*  36:    */ {
     /*  37: 80 */ VariableBase var = this._variable;
     /*  38: 81 */ if (this._variable._ignore) {
       /*  39: 82 */ if ((this._variable instanceof Variable)) {
         /*  40: 83 */ var = parent.getSymbolTable().lookupVariable(this._variable._name);
         /*  41: 85 */ } else if ((this._variable instanceof Param)) {
         /*  42: 86 */ var = parent.getSymbolTable().lookupParam(this._variable._name);
         /*  43:    */ }
       /*  44:    */ }
     /*  45: 90 */ parent.addDependency(var);
     /*  46:    */ }
   /*  47:    */ }