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) else if (eType == formula::ParamClass::ReferenceOrForceArray)
{ {
// Inherit further only if the return class of the nested function is // 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) if (GetForceArrayParameter( rCurr.get(), SAL_MAX_UINT16) != ParamClass::Reference)
rCurr->SetInForceArray( eType); rCurr->SetInForceArray( eType);
else
rCurr->SetInForceArray( formula::ParamClass::SuppressedReferenceOrForceArray);
return; return;
} }
@@ -2595,6 +2597,8 @@ void FormulaCompiler::ForceArrayOperator( FormulaTokenRef const & rCurr )
{ {
if (GetForceArrayParameter( rCurr.get(), SAL_MAX_UINT16) != ParamClass::Reference) if (GetForceArrayParameter( rCurr.get(), SAL_MAX_UINT16) != ParamClass::Reference)
rCurr->SetInForceArray( eType); 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::Array:
case ParamClass::ForceArray: case ParamClass::ForceArray:
case ParamClass::ReferenceOrForceArray: case ParamClass::ReferenceOrForceArray:
case ParamClass::SuppressedReferenceOrForceArray:
; // nothing, only as array/matrix ; // nothing, only as array/matrix
// no default to get compiler warning // no default to get compiler warning
} }

View File

@@ -51,8 +51,15 @@ namespace formula
propagated to subsequent operators and functions being part of a propagated to subsequent operators and functions being part of a
parameter of this function. Used with functions that treat parameter of this function. Used with functions that treat
references separately from arrays, but need the forced array references separately from arrays, but need the forced array
calculation of parameters that are not references.*/ calculation of parameters that are not references. */
ReferenceOrForceArray 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 ) if ( !bCont )
{ // We're done with it, throw away jump matrix, keep result. { // 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. // 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 // Treat the result of a jump command as final and use the matrix (see
// tdf#115493 for why). // tdf#115493 for why).
ParamClass eParamClass;
if (!FormulaCompiler::IsOpCodeJumpCommand( pJumpMatrix->GetOpCode()) && if (!FormulaCompiler::IsOpCodeJumpCommand( pJumpMatrix->GetOpCode()) &&
pJumpMatrix->GetRefList().size() > 1 &&
ScParameterClassification::GetParameterType( pCur, SAL_MAX_UINT16) == ParamClass::Reference && ScParameterClassification::GetParameterType( pCur, SAL_MAX_UINT16) == ParamClass::Reference &&
(eParamClass = pCur->GetInForceArray()) != ParamClass::ForceArray &&
eParamClass != ParamClass::ReferenceOrForceArray &&
eParamClass != ParamClass::SuppressedReferenceOrForceArray &&
aCode.PeekNextOperator()) aCode.PeekNextOperator())
{ {
FormulaTokenRef xRef = new ScRefListToken(true); FormulaTokenRef xRef = new ScRefListToken(true);