formula/source/core/api/FormulaCompiler.cxx |    7 +++++++
 formula/source/core/api/token.cxx           |    2 +-
 formula/source/ui/dlg/formula.cxx           |    1 +
 include/formula/paramclass.hxx              |    7 ++++++-
 sc/source/core/tool/parclass.cxx            |    2 +-
 5 files changed, 16 insertions(+), 3 deletions(-)

New commits:
commit d0ded163d8e93dc5b10d7a7c9bdab1d0a6a50bac
Author:     Eike Rathke <er...@redhat.com>
AuthorDate: Tue Jan 15 19:59:53 2019 +0100
Commit:     Eike Rathke <er...@redhat.com>
CommitDate: Wed Jan 16 11:17:14 2019 +0100

    Related: tdf#122301 FREQUENCY() with ForceArrayReturn on caller
    
    FREQUENCY() forces its direct caller into array mode, but only for
    the immediate subexpression and not for further operators of the
    same parameter.
    
    This weird Excel behaviour is stated in
    
    ECMA-376-1:2016 OOXML 18.17.7.127 FREQUENCY
    "A call to FREQUENCY shall be an array formula."
    
    somewhat unclear what it actually applies to, but it turned out
    that "a call" is indeed *only* THE direct call, see
    https://bugs.documentfoundation.org/show_bug.cgi?id=122301#c19
    
    Change-Id: I145d8fe26d75d5af25b987e190bf35f2d2c03ec6
    Reviewed-on: https://gerrit.libreoffice.org/66407
    Reviewed-by: Eike Rathke <er...@redhat.com>
    Tested-by: Jenkins

diff --git a/formula/source/core/api/FormulaCompiler.cxx 
b/formula/source/core/api/FormulaCompiler.cxx
index da1769d13b17..f243aab357f7 100644
--- a/formula/source/core/api/FormulaCompiler.cxx
+++ b/formula/source/core/api/FormulaCompiler.cxx
@@ -2746,6 +2746,13 @@ void FormulaCompiler::ForceArrayOperator( 
FormulaTokenRef const & rCurr )
             else
                 rCurr->SetInForceArray( 
formula::ParamClass::SuppressedReferenceOrForceArray);
         }
+
+        // Propagate a ForceArrayReturn to caller if the called function
+        // returns one and the caller so far does not have a stronger array
+        // mode set.
+        if (pCurrentFactorToken->GetInForceArray() == ParamClass::Unknown
+                && GetForceArrayParameter( rCurr.get(), SAL_MAX_UINT16) == 
ParamClass::ForceArrayReturn)
+            pCurrentFactorToken->SetInForceArray( 
ParamClass::ForceArrayReturn);
     }
 }
 
diff --git a/formula/source/core/api/token.cxx 
b/formula/source/core/api/token.cxx
index aa3dbec8c8ef..a80897c280fb 100644
--- a/formula/source/core/api/token.cxx
+++ b/formula/source/core/api/token.cxx
@@ -151,7 +151,7 @@ bool FormulaToken::IsInForceArray() const
 {
     ParamClass eParam = GetInForceArray();
     return eParam == ParamClass::ForceArray || eParam == 
ParamClass::ReferenceOrForceArray
-        || eParam == ParamClass::ReferenceOrRefArray;
+        || eParam == ParamClass::ReferenceOrRefArray || eParam == 
ParamClass::ForceArrayReturn;
 }
 
 bool FormulaToken::operator==( const FormulaToken& rToken ) const
diff --git a/formula/source/ui/dlg/formula.cxx 
b/formula/source/ui/dlg/formula.cxx
index adfe4e210f2d..d1052c3a4142 100644
--- a/formula/source/ui/dlg/formula.cxx
+++ b/formula/source/ui/dlg/formula.cxx
@@ -757,6 +757,7 @@ void FormulaDlg_Impl::MakeTree( StructPage* _pTree, 
SvTreeListEntry* pParent, co
                             case ParamClass::ForceArray:
                             case ParamClass::ReferenceOrForceArray:
                             case ParamClass::SuppressedReferenceOrForceArray:
+                            case ParamClass::ForceArrayReturn:
                                 ;   // nothing, only as array/matrix
                             // no default to get compiler warning
                         }
diff --git a/include/formula/paramclass.hxx b/include/formula/paramclass.hxx
index a1e564819457..30773c35e016 100644
--- a/include/formula/paramclass.hxx
+++ b/include/formula/paramclass.hxx
@@ -67,7 +67,12 @@ namespace formula
             Reference in JumpMatrix context should use the result matrix
             instead of the array of references. Never used as initial parameter
             classification. */
-        SuppressedReferenceOrForceArray
+        SuppressedReferenceOrForceArray,
+
+        /** A function return forces the caller into array mode for this one
+            call, making it behave like it had ForceArray but not propagated to
+            any further operators in the same parameter. */
+        ForceArrayReturn
     };
 }
 
diff --git a/sc/source/core/tool/parclass.cxx b/sc/source/core/tool/parclass.cxx
index 4d1672bbd079..ce6c9094cc71 100644
--- a/sc/source/core/tool/parclass.cxx
+++ b/sc/source/core/tool/parclass.cxx
@@ -146,7 +146,7 @@ const ScParameterClassification::RawData 
ScParameterClassification::pRawData[] =
     { ocForecast_ETS_STA, {{ ForceArray, ForceArray, ForceArray, Value, Value, 
Value        }, 0, Value }},
     { ocForecast_ETS_STM, {{ ForceArray, ForceArray, ForceArray, Value, Value, 
Value        }, 0, Value }},
     { ocFormula,         {{ Reference                                          
  }, 0, Value }},
-    { ocFrequency,       {{ ReferenceOrForceArray, ReferenceOrForceArray       
  }, 0, Value }},
+    { ocFrequency,       {{ ReferenceOrForceArray, ReferenceOrForceArray       
  }, 0, ForceArrayReturn }},
     { ocGCD,             {{ Reference                                          
  }, 1, Value }},
     { ocGeoMean,         {{ Reference                                          
  }, 1, Value }},
     { ocGreater,         {{ Array, Array                                       
  }, 0, Value }},
_______________________________________________
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits

Reply via email to