Beispiel #1
0
  /**
   * @return <code>false</code> if sub-expression represented the specified ParseNode definitely
   *     cannot appear on either side of the range (':') operator
   */
  private static boolean isValidRangeOperand(ParseNode a) {
    Ptg tkn = a.getToken();
    // Note - order is important for these instance-of checks
    if (tkn instanceof OperandPtg) {
      // notably cell refs and area refs
      return true;
    }

    // next 2 are special cases of OperationPtg
    if (tkn instanceof AbstractFunctionPtg) {
      AbstractFunctionPtg afp = (AbstractFunctionPtg) tkn;
      byte returnClass = afp.getDefaultOperandClass();
      return Ptg.CLASS_REF == returnClass;
    }
    if (tkn instanceof ValueOperatorPtg) {
      return false;
    }
    if (tkn instanceof OperationPtg) {
      return true;
    }

    // one special case of ControlPtg
    if (tkn instanceof ParenthesisPtg) {
      // parenthesis Ptg should have only one child
      return isValidRangeOperand(a.getChildren()[0]);
    }

    // one special case of ScalarConstantPtg
    if (tkn == ErrPtg.REF_INVALID) {
      return true;
    }

    // All other ControlPtgs and ScalarConstantPtgs cannot be used with ':'
    return false;
  }
 private static boolean isSimpleValueFunction(Ptg token) {
   if (token instanceof AbstractFunctionPtg) {
     AbstractFunctionPtg aptg = (AbstractFunctionPtg) token;
     if (aptg.getDefaultOperandClass() != Ptg.CLASS_VALUE) {
       return false;
     }
     int numberOfOperands = aptg.getNumberOfOperands();
     for (int i = numberOfOperands - 1; i >= 0; i--) {
       if (aptg.getParameterClass(i) != Ptg.CLASS_VALUE) {
         return false;
       }
     }
     return true;
   }
   return false;
 }
  private void transformFunctionNode(
      AbstractFunctionPtg afp,
      ParseNode[] children,
      byte desiredOperandClass,
      boolean callerForceArrayFlag) {

    boolean localForceArrayFlag;
    byte defaultReturnOperandClass = afp.getDefaultOperandClass();

    if (callerForceArrayFlag) {
      switch (defaultReturnOperandClass) {
        case Ptg.CLASS_REF:
          if (desiredOperandClass == Ptg.CLASS_REF) {
            afp.setClass(Ptg.CLASS_REF);
          } else {
            afp.setClass(Ptg.CLASS_ARRAY);
          }
          localForceArrayFlag = false;
          break;
        case Ptg.CLASS_ARRAY:
          afp.setClass(Ptg.CLASS_ARRAY);
          localForceArrayFlag = false;
          break;
        case Ptg.CLASS_VALUE:
          afp.setClass(Ptg.CLASS_ARRAY);
          localForceArrayFlag = true;
          break;
        default:
          throw new IllegalStateException(
              "Unexpected operand class (" + defaultReturnOperandClass + ")");
      }
    } else {
      if (defaultReturnOperandClass == desiredOperandClass) {
        localForceArrayFlag = false;
        // an alternative would have been to for non-base Ptgs to set their operand class
        // from their default, but this would require the call in many subclasses because
        // the default OC is not known until the end of the constructor
        afp.setClass(defaultReturnOperandClass);
      } else {
        switch (desiredOperandClass) {
          case Ptg.CLASS_VALUE:
            // always OK to set functions to return 'value'
            afp.setClass(Ptg.CLASS_VALUE);
            localForceArrayFlag = false;
            break;
          case Ptg.CLASS_ARRAY:
            switch (defaultReturnOperandClass) {
              case Ptg.CLASS_REF:
                afp.setClass(Ptg.CLASS_REF);
                //								afp.setClass(Ptg.CLASS_ARRAY);
                break;
              case Ptg.CLASS_VALUE:
                afp.setClass(Ptg.CLASS_ARRAY);
                break;
              default:
                throw new IllegalStateException(
                    "Unexpected operand class (" + defaultReturnOperandClass + ")");
            }
            localForceArrayFlag = (defaultReturnOperandClass == Ptg.CLASS_VALUE);
            break;
          case Ptg.CLASS_REF:
            switch (defaultReturnOperandClass) {
              case Ptg.CLASS_ARRAY:
                afp.setClass(Ptg.CLASS_ARRAY);
                break;
              case Ptg.CLASS_VALUE:
                afp.setClass(Ptg.CLASS_VALUE);
                break;
              default:
                throw new IllegalStateException(
                    "Unexpected operand class (" + defaultReturnOperandClass + ")");
            }
            localForceArrayFlag = false;
            break;
          default:
            throw new IllegalStateException(
                "Unexpected operand class (" + desiredOperandClass + ")");
        }
      }
    }

    for (int i = 0; i < children.length; i++) {
      ParseNode child = children[i];
      byte paramOperandClass = afp.getParameterClass(i);
      transformNode(child, paramOperandClass, localForceArrayFlag);
    }
  }