poi-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From j...@apache.org
Subject svn commit: r675079 - in /poi/trunk/src: documentation/content/xdocs/ java/org/apache/poi/hssf/model/ testcases/org/apache/poi/hssf/data/ testcases/org/apache/poi/hssf/model/
Date Wed, 09 Jul 2008 01:45:34 GMT
Author: josh
Date: Tue Jul  8 18:45:33 2008
New Revision: 675079

URL: http://svn.apache.org/viewvc?rev=675079&view=rev
Log:
Fix for bug 45348 - required tweaks to RVA formula logic

Modified:
    poi/trunk/src/documentation/content/xdocs/changes.xml
    poi/trunk/src/documentation/content/xdocs/status.xml
    poi/trunk/src/java/org/apache/poi/hssf/model/OperandClassTransformer.java
    poi/trunk/src/testcases/org/apache/poi/hssf/data/testRVA.xls
    poi/trunk/src/testcases/org/apache/poi/hssf/model/TestOperandClassTransformer.java

Modified: poi/trunk/src/documentation/content/xdocs/changes.xml
URL: http://svn.apache.org/viewvc/poi/trunk/src/documentation/content/xdocs/changes.xml?rev=675079&r1=675078&r2=675079&view=diff
==============================================================================
--- poi/trunk/src/documentation/content/xdocs/changes.xml (original)
+++ poi/trunk/src/documentation/content/xdocs/changes.xml Tue Jul  8 18:45:33 2008
@@ -37,6 +37,7 @@
 
 		<!-- Don't forget to update status.xml too! -->
         <release version="3.1.1-alpha1" date="2008-??-??">
+           <action dev="POI-DEVELOPERS" type="fix">45348 - Tweaks to RVA formula logic</action>
            <action dev="POI-DEVELOPERS" type="fix">45354 - Fixed recognition of named
ranges within formulas</action>
            <action dev="POI-DEVELOPERS" type="fix">45338 - Fix HSSFWorkbook to give
you the same HSSFFont every time, and then fix it to find newly added fonts</action>
            <action dev="POI-DEVELOPERS" type="fix">45336 - Fix HSSFColor.getTripletHash()</action>

Modified: poi/trunk/src/documentation/content/xdocs/status.xml
URL: http://svn.apache.org/viewvc/poi/trunk/src/documentation/content/xdocs/status.xml?rev=675079&r1=675078&r2=675079&view=diff
==============================================================================
--- poi/trunk/src/documentation/content/xdocs/status.xml (original)
+++ poi/trunk/src/documentation/content/xdocs/status.xml Tue Jul  8 18:45:33 2008
@@ -34,6 +34,7 @@
 	<!-- Don't forget to update changes.xml too! -->
     <changes>
         <release version="3.1.1-alpha1" date="2008-??-??">
+           <action dev="POI-DEVELOPERS" type="fix">45348 - Tweaks to RVA formula logic</action>
            <action dev="POI-DEVELOPERS" type="fix">45354 - Fixed recognition of named
ranges within formulas</action>
            <action dev="POI-DEVELOPERS" type="fix">45338 - Fix HSSFWorkbook to give
you the same HSSFFont every time, and then fix it to find newly added fonts</action>
            <action dev="POI-DEVELOPERS" type="fix">45336 - Fix HSSFColor.getTripletHash()</action>

Modified: poi/trunk/src/java/org/apache/poi/hssf/model/OperandClassTransformer.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/model/OperandClassTransformer.java?rev=675079&r1=675078&r2=675079&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/model/OperandClassTransformer.java (original)
+++ poi/trunk/src/java/org/apache/poi/hssf/model/OperandClassTransformer.java Tue Jul  8 18:45:33
2008
@@ -71,11 +71,16 @@
 						+ _formulaType + ") not supported yet");
 		
 		}
-		transformNode(rootNode, rootNodeOperandClass, false);
+		transformNode(rootNode, rootNodeOperandClass, false, false);
 	}
 
+	/**
+	 * @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) {
+			boolean callerForceArrayFlag, boolean isDirectChildOfValueOperator) {
 		Ptg token = node.getToken();
 		ParseNode[] children = node.getChildren();
 		if (token instanceof ValueOperatorPtg || token instanceof ControlPtg) {
@@ -84,7 +89,7 @@
 			// but any child nodes are processed according to desiredOperandClass and callerForceArrayFlag
 			for (int i = 0; i < children.length; i++) {
 				ParseNode child = children[i];
-				transformNode(child, desiredOperandClass, callerForceArrayFlag);
+				transformNode(child, desiredOperandClass, callerForceArrayFlag, true);
 			}
 			return;
 		}
@@ -101,22 +106,34 @@
 			// nothing to do
 			return;
 		}
-        if (callerForceArrayFlag) {
-        	switch (desiredOperandClass) {
-        		case Ptg.CLASS_VALUE:
-        		case Ptg.CLASS_ARRAY:
-        			token.setClass(Ptg.CLASS_ARRAY); 
-        			break;
-        		case Ptg.CLASS_REF:
-        			token.setClass(Ptg.CLASS_REF); 
-        			break;
-        		default:
-        			throw new IllegalStateException("Unexpected operand class ("
-        					+ desiredOperandClass + ")");
-        	}
-        } else {
-        	token.setClass(desiredOperandClass);
-        }
+		if (isDirectChildOfValueOperator) {
+			// 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.
+			if (token.getPtgClass() == Ptg.CLASS_REF) {
+				token.setClass(Ptg.CLASS_VALUE); 
+			}
+		}
+		token.setClass(transformClass(token.getPtgClass(), desiredOperandClass, callerForceArrayFlag));
+	}
+
+	private byte transformClass(byte currentOperandClass, byte desiredOperandClass,
+			boolean callerForceArrayFlag) {
+		switch (desiredOperandClass) {
+			case Ptg.CLASS_VALUE:
+				if (!callerForceArrayFlag) {
+					return Ptg.CLASS_VALUE;
+				}
+				// else fall through
+			case Ptg.CLASS_ARRAY:
+				return Ptg.CLASS_ARRAY; 
+			case Ptg.CLASS_REF:
+				if (!callerForceArrayFlag) {
+					return currentOperandClass;
+				}
+				return Ptg.CLASS_REF; 
+		}
+		throw new IllegalStateException("Unexpected operand class (" + desiredOperandClass + ")");
 	}
 
 	private void transformFunctionNode(AbstractFunctionPtg afp, ParseNode[] children,
@@ -200,7 +217,7 @@
 		for (int i = 0; i < children.length; i++) {
 			ParseNode child = children[i];
 			byte paramOperandClass = afp.getParameterClass(i);
-			transformNode(child, paramOperandClass, localForceArrayFlag);
+			transformNode(child, paramOperandClass, localForceArrayFlag, false);
 		}
 	}
 }

Modified: poi/trunk/src/testcases/org/apache/poi/hssf/data/testRVA.xls
URL: http://svn.apache.org/viewvc/poi/trunk/src/testcases/org/apache/poi/hssf/data/testRVA.xls?rev=675079&r1=675078&r2=675079&view=diff
==============================================================================
Binary files - no diff available.

Modified: poi/trunk/src/testcases/org/apache/poi/hssf/model/TestOperandClassTransformer.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/testcases/org/apache/poi/hssf/model/TestOperandClassTransformer.java?rev=675079&r1=675078&r2=675079&view=diff
==============================================================================
--- poi/trunk/src/testcases/org/apache/poi/hssf/model/TestOperandClassTransformer.java (original)
+++ poi/trunk/src/testcases/org/apache/poi/hssf/model/TestOperandClassTransformer.java Tue
Jul  8 18:45:33 2008
@@ -57,6 +57,31 @@
 		confirmFuncClass(ptgs, 2, "INDEX", Ptg.CLASS_VALUE);
 	}
 
+	/**
+	 * Even though count expects args of type R, because A1 is a direct operand of a
+	 * value operator it must get type V
+	 */
+	public void testDirectOperandOfValueOperator() {
+		String formula = "COUNT(A1*1)";
+		Ptg[] ptgs = FormulaParser.parse(formula, null);
+		if (ptgs[0].getPtgClass() == Ptg.CLASS_REF) {
+			throw new AssertionFailedError("Identified bug 45348");
+		}
+
+		confirmTokenClass(ptgs, 0, Ptg.CLASS_VALUE);
+		confirmTokenClass(ptgs, 3, Ptg.CLASS_VALUE);
+	}
+	
+	/**
+	 * A cell ref passed to a function expecting type V should be converted to type V
+	 */
+	public void testRtoV() {
+
+		String formula = "lookup(A1, A3:A52, B3:B52)";
+		Ptg[] ptgs = FormulaParser.parse(formula, null);
+		confirmTokenClass(ptgs, 0, Ptg.CLASS_VALUE);
+	}
+	
 	public void testComplexIRR_bug45041() {
 		String formula = "(1+IRR(SUMIF(A:A,ROW(INDIRECT(MIN(A:A)&\":\"&MAX(A:A))),B:B),0))^365-1";
 		Ptg[] ptgs = FormulaParser.parse(formula, null);
@@ -89,8 +114,11 @@
 
 	private void confirmTokenClass(Ptg[] ptgs, int i, byte operandClass) {
 		Ptg ptg = ptgs[i];
+		if (ptg.isBaseToken()) {
+			throw new AssertionFailedError("ptg[" + i + "] is a base token");
+		}
 		if (operandClass != ptg.getPtgClass()) {
-			throw new AssertionFailedError("Wrong operand class for function ptg ("
+			throw new AssertionFailedError("Wrong operand class for ptg ("
 					+ ptg.toString() + "). Expected " + getOperandClassName(operandClass)
 					+ " but got " + getOperandClassName(ptg.getPtgClass()));
 		}



---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@poi.apache.org
For additional commands, e-mail: commits-help@poi.apache.org


Mime
View raw message