summaryrefslogtreecommitdiff
path: root/formula
diff options
context:
space:
mode:
Diffstat (limited to 'formula')
-rw-r--r--formula/source/core/api/FormulaCompiler.cxx33
-rw-r--r--formula/source/core/api/token.cxx3
-rw-r--r--formula/source/ui/dlg/formula.cxx1
3 files changed, 28 insertions, 9 deletions
diff --git a/formula/source/core/api/FormulaCompiler.cxx b/formula/source/core/api/FormulaCompiler.cxx
index b0938aa630be..ccf4562fec9d 100644
--- a/formula/source/core/api/FormulaCompiler.cxx
+++ b/formula/source/core/api/FormulaCompiler.cxx
@@ -2693,6 +2693,13 @@ formula::ParamClass FormulaCompiler::GetForceArrayParameter( const FormulaToken*
void FormulaCompiler::ForceArrayOperator( FormulaTokenRef const & rCurr )
{
+ if (rCurr->GetInForceArray() != ParamClass::Unknown)
+ // Already set, unnecessary to evaluate again. This happens by calls to
+ // CurrentFactor::operator=() while descending through Factor() and
+ // then ascending back (and down and up, ...),
+ // CheckSetForceArrayParameter() and later PutCode().
+ return;
+
if (!pCurrentFactorToken || (pCurrentFactorToken.get() == rCurr.get()))
return;
@@ -2700,27 +2707,37 @@ void FormulaCompiler::ForceArrayOperator( FormulaTokenRef const & rCurr )
return;
// Inherited parameter class.
- formula::ParamClass eType = pCurrentFactorToken->GetInForceArray();
- if (eType == formula::ParamClass::ForceArray)
- {
- rCurr->SetInForceArray( eType);
+ const formula::ParamClass eForceType = pCurrentFactorToken->GetInForceArray();
+ if (eForceType == ParamClass::ForceArray || eForceType == ParamClass::ReferenceOrRefArray)
+ {
+ // ReferenceOrRefArray was set only if in ForceArray context already,
+ // it is valid for the one function only to indicate the preferred
+ // return type. Propagate as ForceArray if not another parameter
+ // handling ReferenceOrRefArray.
+ if (nCurrentFactorParam > 0
+ && (GetForceArrayParameter( pCurrentFactorToken.get(), static_cast<sal_uInt16>(nCurrentFactorParam - 1))
+ == ParamClass::ReferenceOrRefArray))
+ rCurr->SetInForceArray( ParamClass::ReferenceOrRefArray);
+ else
+ rCurr->SetInForceArray( ParamClass::ForceArray);
return;
}
- else if (eType == formula::ParamClass::ReferenceOrForceArray)
+ else if (eForceType == ParamClass::ReferenceOrForceArray)
{
// Inherit further only if the return class of the nested function is
// not Reference. Else flag as suppressed.
if (GetForceArrayParameter( rCurr.get(), SAL_MAX_UINT16) != ParamClass::Reference)
- rCurr->SetInForceArray( eType);
+ rCurr->SetInForceArray( eForceType);
else
- rCurr->SetInForceArray( formula::ParamClass::SuppressedReferenceOrForceArray);
+ rCurr->SetInForceArray( ParamClass::SuppressedReferenceOrForceArray);
return;
}
if (nCurrentFactorParam > 0)
{
// Actual current parameter's class.
- eType = GetForceArrayParameter( pCurrentFactorToken.get(), static_cast<sal_uInt16>(nCurrentFactorParam - 1));
+ const formula::ParamClass eType = GetForceArrayParameter(
+ pCurrentFactorToken.get(), static_cast<sal_uInt16>(nCurrentFactorParam - 1));
if (eType == ParamClass::ForceArray)
rCurr->SetInForceArray( eType);
else if (eType == ParamClass::ReferenceOrForceArray)
diff --git a/formula/source/core/api/token.cxx b/formula/source/core/api/token.cxx
index cefab324fd53..aa3dbec8c8ef 100644
--- a/formula/source/core/api/token.cxx
+++ b/formula/source/core/api/token.cxx
@@ -150,7 +150,8 @@ bool FormulaToken::IsRef() const
bool FormulaToken::IsInForceArray() const
{
ParamClass eParam = GetInForceArray();
- return eParam == ParamClass::ForceArray || eParam == ParamClass::ReferenceOrForceArray;
+ return eParam == ParamClass::ForceArray || eParam == ParamClass::ReferenceOrForceArray
+ || eParam == ParamClass::ReferenceOrRefArray;
}
bool FormulaToken::operator==( const FormulaToken& rToken ) const
diff --git a/formula/source/ui/dlg/formula.cxx b/formula/source/ui/dlg/formula.cxx
index c324be63a943..55135ebc11cf 100644
--- a/formula/source/ui/dlg/formula.cxx
+++ b/formula/source/ui/dlg/formula.cxx
@@ -753,6 +753,7 @@ void FormulaDlg_Impl::MakeTree( StructPage* _pTree, SvTreeListEntry* pParent, co
aUnforcedResult.clear();
break;
case ParamClass::Reference:
+ case ParamClass::ReferenceOrRefArray:
case ParamClass::Array:
case ParamClass::ForceArray:
case ParamClass::ReferenceOrForceArray: