/** * @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; }
/** * Note - Excel function names are 'case aware but not case sensitive'. This method may end up * creating a defined name record in the workbook if the specified name is not an internal Excel * function, and has not been encountered before. * * @param name case preserved function name (as it was entered/appeared in the formula). */ private ParseNode function(String name) { Ptg nameToken = null; if (!AbstractFunctionPtg.isBuiltInFunctionName(name)) { // user defined function // in the token tree, the name is more or less the first argument if (_book == null) { // Only test cases omit the book (expecting it not to be needed) throw new IllegalStateException("Need book to evaluate name '" + name + "'"); } // 20101112, [email protected]: shall provide a temporary defined named record // EvaluationName hName = _book.getName(name, _sheetIndex); EvaluationName hName = _book.getOrCreateName(name, _sheetIndex); if (hName == null) { nameToken = _book.getNameXPtg(name); if (nameToken == null) { throw new FormulaParseException( "Name '" + name + "' is completely unknown in the current workbook"); } } else { // 20101112, [email protected]: unnecessary check /* if (!hName.isFunctionName()) { throw new FormulaParseException("Attempt to use name '" + name + "' as a function, but defined name in workbook does not refer to a function"); } */ // calls to user-defined functions within the workbook // get a Name token which points to a defined name record nameToken = hName.createPtg(); } } Match('('); ParseNode[] args = Arguments(); Match(')'); return getFunction(name, nameToken, args); }