Resolves: tdf#116215 fewer array of references cases, tdf#58874 related

In particular if in any ForceArray context use the matrix result
instead of the array of references list.

Change-Id: I72328a690760637f6d31fadba447641c64711a67
This commit is contained in:
Eike Rathke 2018-03-06 18:41:56 +01:00
parent f775b5427b
commit cfc6cf5177
4 changed files with 23 additions and 4 deletions

View File

@ -2579,9 +2579,11 @@ void FormulaCompiler::ForceArrayOperator( FormulaTokenRef const & rCurr )
else if (eType == formula::ParamClass::ReferenceOrForceArray)
{
// Inherit further only if the return class of the nested function is
// not Reference.
// not Reference. Else flag as suppressed.
if (GetForceArrayParameter( rCurr.get(), SAL_MAX_UINT16) != ParamClass::Reference)
rCurr->SetInForceArray( eType);
else
rCurr->SetInForceArray( formula::ParamClass::SuppressedReferenceOrForceArray);
return;
}
@ -2595,6 +2597,8 @@ void FormulaCompiler::ForceArrayOperator( FormulaTokenRef const & rCurr )
{
if (GetForceArrayParameter( rCurr.get(), SAL_MAX_UINT16) != ParamClass::Reference)
rCurr->SetInForceArray( eType);
else
rCurr->SetInForceArray( formula::ParamClass::SuppressedReferenceOrForceArray);
}
}
}

View File

@ -762,6 +762,7 @@ void FormulaDlg_Impl::MakeTree( StructPage* _pTree, SvTreeListEntry* pParent, co
case ParamClass::Array:
case ParamClass::ForceArray:
case ParamClass::ReferenceOrForceArray:
case ParamClass::SuppressedReferenceOrForceArray:
; // nothing, only as array/matrix
// no default to get compiler warning
}

View File

@ -51,8 +51,15 @@ namespace formula
propagated to subsequent operators and functions being part of a
parameter of this function. Used with functions that treat
references separately from arrays, but need the forced array
calculation of parameters that are not references.*/
ReferenceOrForceArray
calculation of parameters that are not references. */
ReferenceOrForceArray,
/** Same as ReferenceOrForceArray but suppressed / not inherited in the
compiler's ForceArray context to indicate that a result of
Reference in JumpMatrix context should use the result matrix
instead of the array of references. Never used as initial parameter
classification. */
SuppressedReferenceOrForceArray
};
}

View File

@ -800,12 +800,19 @@ bool ScInterpreter::JumpMatrix( short nStackLevel )
}
if ( !bCont )
{ // We're done with it, throw away jump matrix, keep result.
// For an intermediate result of Reference use the array of references,
// For an intermediate result of Reference use the array of references
// if there are more than one reference and the current ForceArray
// context is not ForceArray or related, suppressed, ...,
// else (also for a final result of Reference) use the matrix.
// Treat the result of a jump command as final and use the matrix (see
// tdf#115493 for why).
ParamClass eParamClass;
if (!FormulaCompiler::IsOpCodeJumpCommand( pJumpMatrix->GetOpCode()) &&
pJumpMatrix->GetRefList().size() > 1 &&
ScParameterClassification::GetParameterType( pCur, SAL_MAX_UINT16) == ParamClass::Reference &&
(eParamClass = pCur->GetInForceArray()) != ParamClass::ForceArray &&
eParamClass != ParamClass::ReferenceOrForceArray &&
eParamClass != ParamClass::SuppressedReferenceOrForceArray &&
aCode.PeekNextOperator())
{
FormulaTokenRef xRef = new ScRefListToken(true);