use of org.apache.poi.ss.formula.ptg.AbstractFunctionPtg in project poi by apache.
the class OperandClassTransformer method isSimpleValueFunction.
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;
}
use of org.apache.poi.ss.formula.ptg.AbstractFunctionPtg in project poi by apache.
the class OperandClassTransformer method transformNode.
/**
* @param callerForceArrayFlag <code>true</code> if one of the current node's parents is a
* function Ptg which has been changed from default 'V' to 'A' type (due to requirements on
* the function return value).
*/
private void transformNode(ParseNode node, byte desiredOperandClass, boolean callerForceArrayFlag) {
Ptg token = node.getToken();
ParseNode[] children = node.getChildren();
boolean isSimpleValueFunc = isSimpleValueFunction(token);
if (isSimpleValueFunc) {
boolean localForceArray = desiredOperandClass == Ptg.CLASS_ARRAY;
for (int i = 0; i < children.length; i++) {
transformNode(children[i], desiredOperandClass, localForceArray);
}
setSimpleValueFuncClass((AbstractFunctionPtg) token, desiredOperandClass, callerForceArrayFlag);
return;
}
if (isSingleArgSum(token)) {
// Need to process the argument of SUM with transformFunctionNode below
// so make a dummy FuncVarPtg for that call.
token = FuncVarPtg.SUM;
// Note - the tAttrSum token (node.getToken()) is a base
// token so does not need to have its operand class set
}
if (token instanceof ValueOperatorPtg || token instanceof ControlPtg || token instanceof MemFuncPtg || token instanceof MemAreaPtg || token instanceof UnionPtg || token instanceof IntersectionPtg) {
// Value Operator Ptgs and Control are base tokens, so token will be unchanged
// but any child nodes are processed according to desiredOperandClass and callerForceArrayFlag
// As per OOO documentation Sec 3.2.4 "Token Class Transformation", "Step 1"
// All direct operands of value operators that are initially 'R' type will
// be converted to 'V' type.
byte localDesiredOperandClass = desiredOperandClass == Ptg.CLASS_REF ? Ptg.CLASS_VALUE : desiredOperandClass;
for (int i = 0; i < children.length; i++) {
transformNode(children[i], localDesiredOperandClass, callerForceArrayFlag);
}
return;
}
if (token instanceof AbstractFunctionPtg) {
transformFunctionNode((AbstractFunctionPtg) token, children, desiredOperandClass, callerForceArrayFlag);
return;
}
if (children.length > 0) {
if (token == RangePtg.instance) {
// TODO is any token transformation required under the various ref operators?
return;
}
throw new IllegalStateException("Node should not have any children");
}
if (token.isBaseToken()) {
// nothing to do
return;
}
token.setClass(transformClass(token.getPtgClass(), desiredOperandClass, callerForceArrayFlag));
}
use of org.apache.poi.ss.formula.ptg.AbstractFunctionPtg in project poi by apache.
the class OperationEvaluatorFactory method evaluate.
/**
* returns the OperationEval concrete impl instance corresponding
* to the supplied operationPtg
*/
public static ValueEval evaluate(OperationPtg ptg, ValueEval[] args, OperationEvaluationContext ec) {
if (ptg == null) {
throw new IllegalArgumentException("ptg must not be null");
}
Function result = _instancesByPtgClass.get(ptg);
if (result != null) {
return result.evaluate(args, ec.getRowIndex(), (short) ec.getColumnIndex());
}
if (ptg instanceof AbstractFunctionPtg) {
AbstractFunctionPtg fptg = (AbstractFunctionPtg) ptg;
int functionIndex = fptg.getFunctionIndex();
switch(functionIndex) {
case FunctionMetadataRegistry.FUNCTION_INDEX_INDIRECT:
return Indirect.instance.evaluate(args, ec);
case FunctionMetadataRegistry.FUNCTION_INDEX_EXTERNAL:
return UserDefinedFunction.instance.evaluate(args, ec);
}
return FunctionEval.getBasicFunction(functionIndex).evaluate(args, ec.getRowIndex(), (short) ec.getColumnIndex());
}
throw new RuntimeException("Unexpected operation ptg class (" + ptg.getClass().getName() + ")");
}
use of org.apache.poi.ss.formula.ptg.AbstractFunctionPtg in project poi by apache.
the class TestOperandClassTransformer method confirmFuncClass.
private void confirmFuncClass(Ptg[] ptgs, int i, String expectedFunctionName, byte operandClass) {
confirmTokenClass(ptgs, i, operandClass);
AbstractFunctionPtg afp = (AbstractFunctionPtg) ptgs[i];
assertEquals(expectedFunctionName, afp.getName());
}
Aggregations