Coverage Report

Created: 2026-07-10 11:04

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/sc/inc/tokenarray.hxx
Line
Count
Source
1
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
/*
3
 * This file is part of the LibreOffice project.
4
 *
5
 * This Source Code Form is subject to the terms of the Mozilla Public
6
 * License, v. 2.0. If a copy of the MPL was not distributed with this
7
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8
 *
9
 * This file incorporates work covered by the following license notice:
10
 *
11
 *   Licensed to the Apache Software Foundation (ASF) under one or more
12
 *   contributor license agreements. See the NOTICE file distributed
13
 *   with this work for additional information regarding copyright
14
 *   ownership. The ASF licenses this file to you under the Apache
15
 *   License, Version 2.0 (the "License"); you may not use this file
16
 *   except in compliance with the License. You may obtain a copy of
17
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
18
 */
19
20
#pragma once
21
22
#include <formula/token.hxx>
23
#include <rtl/ref.hxx>
24
#include "document.hxx"
25
#include "scdllapi.h"
26
#include "types.hxx"
27
#include "calcmacros.hxx"
28
#include "address.hxx"
29
#include "global.hxx"
30
#include <formula/tokenarray.hxx>
31
32
namespace sc {
33
34
struct RefUpdateContext;
35
struct RefUpdateInsertTabContext;
36
struct RefUpdateDeleteTabContext;
37
struct RefUpdateMoveTabContext;
38
struct RefUpdateResult;
39
struct TokenStringContext;
40
class ColRowReorderMapType;
41
42
/** If the target tab was inserted, or an existing tab was used. */
43
enum class TargetTabState
44
{
45
    Existing,
46
    Inserted,
47
};
48
49
}
50
51
struct ScRawToken;
52
struct ScSingleRefData;
53
struct ScComplexRefData;
54
55
class SAL_WARN_UNUSED SAL_DLLPUBLIC_RTTI ScTokenArray final : public formula::FormulaTokenArray
56
{
57
    friend class ScCompiler;
58
59
    bool ImplGetReference( ScRange& rRange, const ScAddress& rPos, bool bValidOnly ) const;
60
61
    // hold a reference to the limits because sometimes our lifetime exceeds the lifetime of the associated ScDocument
62
    rtl::Reference<ScSheetLimits> mxSheetLimits;
63
    size_t mnHashValue;
64
    ScFormulaVectorState meVectorState : 4; // Only 4 bits
65
    bool mbOpenCLEnabled : 1;
66
    bool mbThreadingEnabled : 1;
67
68
    void CheckForThreading( const formula::FormulaToken& r );
69
70
public:
71
    SC_DLLPUBLIC ScTokenArray(const ScDocument& rDoc);
72
    ScTokenArray(ScSheetLimits&);
73
    /** Assignment with incrementing references of FormulaToken entries
74
        (not copied!) */
75
1.29M
    ScTokenArray( const ScTokenArray& ) = default;
76
1.21M
    ScTokenArray( ScTokenArray&& ) = default;
77
    SC_DLLPUBLIC virtual ~ScTokenArray() override;
78
79
    bool EqualTokens( const ScTokenArray* pArr2 ) const;
80
81
    SC_DLLPUBLIC virtual void Clear() override;
82
    SC_DLLPUBLIC std::unique_ptr<ScTokenArray> Clone() const;    /// True copy!
83
    SC_DLLPUBLIC ScTokenArray CloneValue() const;    /// True copy!
84
85
    SC_DLLPUBLIC void GenHash();
86
31.7M
    size_t GetHash() const { return mnHashValue;}
87
88
93.8k
    ScFormulaVectorState GetVectorState() const { return meVectorState;}
89
    void ResetVectorState();
90
    bool IsFormulaVectorDisabled() const;
91
92
    /**
93
     * If the array contains at least one relative row reference or named
94
     * expression, it's variant. Otherwise invariant.
95
     */
96
    bool IsInvariant() const;
97
98
    /// Exactly and only one range (valid or deleted)
99
    SC_DLLPUBLIC bool IsReference( ScRange& rRange, const ScAddress& rPos ) const;
100
    /// Exactly and only one valid range (no #REF!s)
101
    SC_DLLPUBLIC bool IsValidReference( ScRange& rRange, const ScAddress& rPos ) const;
102
103
                            /** Determines the extent of direct adjacent
104
                                references. Only use with real functions, e.g.
105
                                GetOuterFuncOpCode() == ocSum ! */
106
    bool                    GetAdjacentExtendOfOuterFuncRefs(
107
                                SCCOLROW& nExtend,
108
                                const ScAddress& rPos, ScDirection );
109
110
    formula::FormulaToken* AddRawToken( const ScRawToken& );
111
    SC_DLLPUBLIC virtual bool AddFormulaToken(
112
        const css::sheet::FormulaToken& rToken,
113
        svl::SharedStringPool& rSPool,
114
        formula::ExternalReferenceHelper* _pRef) override;
115
    SC_DLLPUBLIC virtual void CheckToken( const formula::FormulaToken& r ) override;
116
    SC_DLLPUBLIC virtual formula::FormulaToken* AddOpCode( OpCode eCode ) override;
117
    /** ScSingleRefToken with ocPush. */
118
    SC_DLLPUBLIC formula::FormulaToken* AddSingleReference( const ScSingleRefData& rRef );
119
    /** ScSingleRefOpToken with ocMatRef. */
120
    formula::FormulaToken* AddMatrixSingleReference( const ScSingleRefData& rRef );
121
    SC_DLLPUBLIC formula::FormulaToken* AddDoubleReference( const ScComplexRefData& rRef );
122
    SC_DLLPUBLIC void      AddRangeName( sal_uInt16 n, sal_Int16 nSheet );
123
    formula::FormulaToken* AddDBRange( sal_uInt16 n );
124
    SC_DLLPUBLIC formula::FormulaToken* AddTableRef( sal_uInt16 n );
125
    SC_DLLPUBLIC formula::FormulaToken* AddExternalName( sal_uInt16 nFileId, const svl::SharedString& rName );
126
    SC_DLLPUBLIC void AddExternalSingleReference( sal_uInt16 nFileId, const svl::SharedString& rTabName, const ScSingleRefData& rRef );
127
    SC_DLLPUBLIC formula::FormulaToken* AddExternalDoubleReference( sal_uInt16 nFileId, const svl::SharedString& rTabName, const ScComplexRefData& rRef );
128
    SC_DLLPUBLIC formula::FormulaToken* AddMatrix( const ScMatrixRef& p );
129
    /** ScSingleRefOpToken with ocColRowName. */
130
    SC_DLLPUBLIC formula::FormulaToken* AddColRowName( const ScSingleRefData& rRef );
131
    SC_DLLPUBLIC virtual formula::FormulaToken* MergeArray( ) override;
132
133
    /** Merge very last SingleRef+ocRange+SingleRef combination into DoubleRef
134
        and adjust pCode array, or do nothing if conditions not met. */
135
    void MergeRangeReference( const ScAddress & rPos );
136
137
    /// Assign XML string placeholder to the array
138
    void AssignXMLString( const OUString &rText, const OUString &rFormulaNmsp );
139
140
    /** Assignment with incrementing references of FormulaToken entries
141
        (not copied!) */
142
    ScTokenArray& operator=( const ScTokenArray& );
143
    ScTokenArray& operator=( ScTokenArray&& );
144
145
    /**
146
     * Make all absolute references external references pointing to the old document
147
     *
148
     * @param rOldDoc old document
149
     * @param rNewDoc new document
150
     * @param rPos position of the cell to determine if the reference is in the copied area
151
     * @param bRangeName set for range names, range names have special handling for absolute sheet ref + relative col/row ref
152
     */
153
    void ReadjustAbsolute3DReferences( const ScDocument& rOldDoc, ScDocument& rNewDoc, const ScAddress& rPos, bool bRangeName = false );
154
155
    /**
156
     * Make all absolute references pointing to the copied range if the range is copied too
157
     * @param bCheckCopyArea should reference pointing into the copy area be adjusted independently from being absolute, should be true only for copy&paste between documents
158
     */
159
    void AdjustAbsoluteRefs( const ScDocument& rOldDoc, const ScAddress& rOldPos, const ScAddress& rNewPos, bool bCheckCopyArea );
160
161
    /** Adjust relative tab references when copying a formula to a new table.
162
        Non-zero relative tab offsets are recalculated so they still resolve
163
        to the original target sheet from the new position. Same-sheet
164
        relative refs (offset 0) are not modified.
165
        If the target tab was newly inserted, the references pointing to
166
        tabs at or after the insertion point are additionally shifted by
167
        one. */
168
    void AdjustRelativeTabRefs(SCTAB nOldTab, SCTAB nNewTab,
169
        sc::TargetTabState eMode = sc::TargetTabState::Existing);
170
171
    /** When copying a sheet-local named expression, move sheet references that
172
        point to the originating sheet to point to the new sheet instead.
173
     */
174
    void AdjustSheetLocalNameReferences( SCTAB nOldTab, SCTAB nNewTab );
175
176
    /** Returns true if the sheet nTab is referenced in code. Relative sheet
177
        references are evaluated using nPosTab.
178
     */
179
    bool ReferencesSheet( SCTAB nTab, SCTAB nPosTab ) const;
180
181
    /**
182
     * Adjust all references in response to shifting of cells during cell
183
     * insertion and deletion.
184
     *
185
     * @param rCxt context that stores details of shifted region.
186
     * @param rOldPos old cell position prior to shifting.
187
     */
188
    sc::RefUpdateResult AdjustReferenceOnShift( const sc::RefUpdateContext& rCxt, const ScAddress& rOldPos );
189
190
    sc::RefUpdateResult AdjustReferenceOnMove(
191
        const sc::RefUpdateContext& rCxt, const ScAddress& rOldPos, const ScAddress& rNewPos );
192
193
    /**
194
     * Move reference positions in response to column reordering.  A range
195
     * reference gets moved only when the whole range fits in a single column.
196
     *
197
     * @param rPos position of this formula cell
198
     * @param nTab sheet where columns are reordered.
199
     * @param nRow1 top row of reordered range.
200
     * @param nRow2 bottom row of reordered range.
201
     * @param rColMap old-to-new column mapping.
202
     */
203
    void MoveReferenceColReorder(
204
        const ScAddress& rPos, SCTAB nTab, SCROW nRow1, SCROW nRow2,
205
        const sc::ColRowReorderMapType& rColMap );
206
207
    void MoveReferenceRowReorder(
208
        const ScAddress& rPos, SCTAB nTab, SCCOL nCol1, SCCOL nCol2,
209
        const sc::ColRowReorderMapType& rRowMap );
210
211
    /**
212
     * Adjust all references in named expression. In named expression, we only
213
     * update absolute positions, and leave relative positions intact.
214
     *
215
     * @param rCxt context that stores details of shifted region
216
     *
217
     * @return update result.
218
     */
219
    sc::RefUpdateResult AdjustReferenceInName( const sc::RefUpdateContext& rCxt, const ScAddress& rPos );
220
221
    sc::RefUpdateResult AdjustReferenceInMovedName( const sc::RefUpdateContext& rCxt, const ScAddress& rPos );
222
223
    /**
224
     * Adjust all references on sheet deletion.
225
     *
226
     * @param nDelPos position of sheet being deleted.
227
     * @param nSheets number of sheets to delete.
228
     * @param rOldPos position of formula cell prior to the deletion.
229
     *
230
     * @return true if at least one reference has changed its sheet reference.
231
     */
232
    sc::RefUpdateResult AdjustReferenceOnDeletedTab( const sc::RefUpdateDeleteTabContext& rCxt, const ScAddress& rOldPos );
233
234
    sc::RefUpdateResult AdjustReferenceOnInsertedTab( const sc::RefUpdateInsertTabContext& rCxt, const ScAddress& rOldPos );
235
236
    sc::RefUpdateResult AdjustReferenceOnMovedTab( const sc::RefUpdateMoveTabContext& rCxt, const ScAddress& rOldPos );
237
238
    /**
239
     * Adjust all internal references on base position change.
240
     */
241
    void AdjustReferenceOnMovedOrigin( const ScAddress& rOldPos, const ScAddress& rNewPos );
242
243
    /**
244
     * Adjust all internal references on base position change if they point to
245
     * a sheet other than the one of rOldPos.
246
     */
247
    void AdjustReferenceOnMovedOriginIfOtherSheet( const ScAddress& rOldPos, const ScAddress& rNewPos );
248
249
    /**
250
     * Adjust internal range references on base position change to justify /
251
     * put in order the relative references.
252
     */
253
    void AdjustReferenceOnCopy( const ScAddress& rNewPos );
254
255
    /**
256
     * Clear sheet deleted flag from internal reference tokens if the sheet
257
     * index falls within specified range.  Note that when a reference is on a
258
     * sheet that's been deleted, its referenced sheet index retains the
259
     * original index of the deleted sheet.
260
     *
261
     * @param rPos position of formula cell
262
     * @param nStartTab index of first sheet, inclusive.
263
     * @param nEndTab index of last sheet, inclusive.
264
     */
265
    void ClearTabDeleted( const ScAddress& rPos, SCTAB nStartTab, SCTAB nEndTab );
266
267
    void CheckRelativeReferenceBounds(
268
        const sc::RefUpdateContext& rCxt, const ScAddress& rPos, SCROW nGroupLen, std::vector<SCROW>& rBounds ) const;
269
270
    void CheckRelativeReferenceBounds(
271
        const ScAddress& rPos, SCROW nGroupLen, const ScRange& rRange, std::vector<SCROW>& rBounds ) const;
272
273
    void CheckExpandReferenceBounds(
274
        const sc::RefUpdateContext& rCxt, const ScAddress& rPos, SCROW nGroupLen, std::vector<SCROW>& rBounds ) const;
275
276
    /**
277
     * Create a string representation of formula token array without modifying
278
     * the internal state of the token array.
279
     */
280
    SC_DLLPUBLIC OUString CreateString( sc::TokenStringContext& rCxt, const ScAddress& rPos ) const;
281
282
    SC_DLLPUBLIC void WrapReference( const ScAddress& rPos, SCCOL nMaxCol, SCROW nMaxRow );
283
284
    sal_Int32 GetWeight() const;
285
286
93.8k
    bool IsEnabledForOpenCL() const { return mbOpenCLEnabled; }
287
0
    bool IsEnabledForThreading() const { return mbThreadingEnabled; }
288
289
#if DEBUG_FORMULA_COMPILER
290
    void Dump() const;
291
#endif
292
};
293
294
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */