summaryrefslogtreecommitdiff
path: root/formula
diff options
context:
space:
mode:
authorEike Rathke <erack@redhat.com>2018-11-09 12:39:40 +0100
committerEike Rathke <erack@redhat.com>2018-11-09 19:14:09 +0100
commit6ce84da750abcec3139bf12bc212fb2f03460add (patch)
treec8c333458a924bd1c33ed1c233f88888e7a7d43a /formula
parent717cdaf4bc864e0b96bfba5f3bc557afe751f50f (diff)
Resolves: tdf#120895 new ParamClass::ReferenceOrRefArray, tdf#58874 related
Too many side conditions are possible with implicit array of references in array mode. Propagate new ReferenceOrRefArray parameter class to indicate the preferred return type for arguments to functions whose parameters explicitly handle array of references. Change-Id: I1f01266495c2ef1941ffe0cb7c2e0a5ae0bb7e69 Reviewed-on: https://gerrit.libreoffice.org/63201 Reviewed-by: Eike Rathke <erack@redhat.com> Tested-by: Jenkins
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: