@bilig/formula 0.7.8 → 0.8.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/binder-wasm-arity.d.ts +1 -0
- package/dist/binder-wasm-arity.js +541 -0
- package/dist/binder-wasm-arity.js.map +1 -0
- package/dist/binder-wasm-rules.d.ts +1 -2
- package/dist/binder-wasm-rules.js +2 -540
- package/dist/binder-wasm-rules.js.map +1 -1
- package/dist/builtins/cell-value-utils.d.ts +9 -0
- package/dist/builtins/cell-value-utils.js +63 -0
- package/dist/builtins/cell-value-utils.js.map +1 -0
- package/dist/builtins/datetime.d.ts +2 -10
- package/dist/builtins/datetime.js +5 -261
- package/dist/builtins/datetime.js.map +1 -1
- package/dist/builtins/excel-date.d.ts +16 -0
- package/dist/builtins/excel-date.js +199 -0
- package/dist/builtins/excel-date.js.map +1 -0
- package/dist/builtins/lookup-core-helpers.d.ts +50 -0
- package/dist/builtins/lookup-core-helpers.js +342 -0
- package/dist/builtins/lookup-core-helpers.js.map +1 -0
- package/dist/builtins/lookup.d.ts +3 -25
- package/dist/builtins/lookup.js +3 -341
- package/dist/builtins/lookup.js.map +1 -1
- package/dist/formula-reference-translation.d.ts +20 -0
- package/dist/formula-reference-translation.js +273 -0
- package/dist/formula-reference-translation.js.map +1 -0
- package/dist/formula-serializer.d.ts +2 -0
- package/dist/formula-serializer.js +74 -0
- package/dist/formula-serializer.js.map +1 -0
- package/dist/formula-sheet-rename.d.ts +14 -0
- package/dist/formula-sheet-rename.js +243 -0
- package/dist/formula-sheet-rename.js.map +1 -0
- package/dist/formula-structural-rewrite.d.ts +14 -0
- package/dist/formula-structural-rewrite.js +511 -0
- package/dist/formula-structural-rewrite.js.map +1 -0
- package/dist/formula-template-key.d.ts +2 -0
- package/dist/formula-template-key.js +58 -0
- package/dist/formula-template-key.js.map +1 -1
- package/dist/js-evaluator-cell-values.d.ts +5 -0
- package/dist/js-evaluator-cell-values.js +14 -0
- package/dist/js-evaluator-cell-values.js.map +1 -0
- package/dist/js-evaluator-context-special-calls.js +72 -0
- package/dist/js-evaluator-context-special-calls.js.map +1 -1
- package/dist/js-evaluator-runtime-helpers.d.ts +39 -0
- package/dist/js-evaluator-runtime-helpers.js +453 -0
- package/dist/js-evaluator-runtime-helpers.js.map +1 -0
- package/dist/js-evaluator-types.d.ts +178 -0
- package/dist/js-evaluator-types.js +2 -0
- package/dist/js-evaluator-types.js.map +1 -0
- package/dist/js-evaluator.d.ts +4 -178
- package/dist/js-evaluator.js +3 -463
- package/dist/js-evaluator.js.map +1 -1
- package/dist/translation-reference-utils.d.ts +42 -0
- package/dist/translation-reference-utils.js +178 -0
- package/dist/translation-reference-utils.js.map +1 -0
- package/dist/translation.d.ts +6 -32
- package/dist/translation.js +14 -1300
- package/dist/translation.js.map +1 -1
- package/package.json +2 -2
package/dist/translation.js
CHANGED
|
@@ -1,37 +1,13 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import { compileFormulaAst, } from './compiler.js';
|
|
1
|
+
import { FormulaMode } from '@bilig/protocol';
|
|
2
|
+
import { parseRangeAddress } from './addressing.js';
|
|
4
3
|
import { parseFormula } from './parser.js';
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
'>=': 1,
|
|
13
|
-
'<': 1,
|
|
14
|
-
'<=': 1,
|
|
15
|
-
'&': 2,
|
|
16
|
-
'+': 3,
|
|
17
|
-
'-': 3,
|
|
18
|
-
'*': 4,
|
|
19
|
-
'/': 4,
|
|
20
|
-
'^': 5,
|
|
21
|
-
};
|
|
22
|
-
function assertNever(value) {
|
|
23
|
-
throw new Error(`Unexpected value: ${String(value)}`);
|
|
24
|
-
}
|
|
25
|
-
const ERROR_LITERAL_TEXT = {
|
|
26
|
-
[ErrorCode.Ref]: '#REF!',
|
|
27
|
-
[ErrorCode.Name]: '#NAME?',
|
|
28
|
-
[ErrorCode.Div0]: '#DIV/0!',
|
|
29
|
-
[ErrorCode.NA]: '#N/A',
|
|
30
|
-
[ErrorCode.Value]: '#VALUE!',
|
|
31
|
-
[ErrorCode.Cycle]: '#CYCLE!',
|
|
32
|
-
[ErrorCode.Spill]: '#SPILL!',
|
|
33
|
-
[ErrorCode.Blocked]: '#BLOCKED!',
|
|
34
|
-
};
|
|
4
|
+
import { serializeFormula } from './formula-serializer.js';
|
|
5
|
+
import { buildRelativeFormulaTemplateAstKey } from './formula-template-key.js';
|
|
6
|
+
import { renameCompiledFormulaSheetReferenceMetadata as renameCompiledFormulaSheetReferenceMetadataImpl, renameCompiledFormulaSheetReferenceMetadataInPlace as renameCompiledFormulaSheetReferenceMetadataInPlaceImpl, renameCompiledFormulaSheetReferences as renameCompiledFormulaSheetReferencesImpl, renameFormulaSheetReferences as renameFormulaSheetReferencesImpl, } from './formula-sheet-rename.js';
|
|
7
|
+
import { buildTranslatedCellReferenceMap, buildTranslatedRangeReferenceMap, formatParsedCellReference, formatParsedDependencyReference, formatParsedLocalCellReference, formatParsedRangeReference, translatedCellInstructionKey, translatedRangeInstructionKey, translateCellReference, translateColumnReference, translateParsedCellReference, translateParsedDependencyReference, translateParsedRangeReference, translateQualifiedCellReference, translateQualifiedDependencyReference, translateQualifiedRangeReference, translateRangeAddress, translateRowReference, } from './formula-reference-translation.js';
|
|
8
|
+
import { quoteSheetNameIfNeeded } from './translation-reference-utils.js';
|
|
9
|
+
export { rewriteAddressForStructuralTransform, rewriteCompiledFormulaForStructuralTransform, rewriteFormulaForStructuralTransform, rewriteRangeForStructuralTransform, } from './formula-structural-rewrite.js';
|
|
10
|
+
export { serializeFormula } from './formula-serializer.js';
|
|
35
11
|
export function translateFormulaReferences(source, rowDelta, colDelta) {
|
|
36
12
|
const ast = parseFormula(source);
|
|
37
13
|
return serializeFormula(translateNode(ast, rowDelta, colDelta));
|
|
@@ -40,7 +16,7 @@ export function buildRelativeFormulaTemplateKey(source, ownerRow, ownerCol) {
|
|
|
40
16
|
return buildRelativeFormulaTemplateKeyFromAst(parseFormula(source), ownerRow, ownerCol);
|
|
41
17
|
}
|
|
42
18
|
export function buildRelativeFormulaTemplateKeyFromAst(node, ownerRow, ownerCol) {
|
|
43
|
-
return
|
|
19
|
+
return buildRelativeFormulaTemplateAstKey(node, ownerRow, ownerCol);
|
|
44
20
|
}
|
|
45
21
|
export function canTranslateCompiledFormulaWithoutAst(compiled) {
|
|
46
22
|
return ((compiled.symbolicRanges.length === 0 || compiled.directAggregateCandidate !== undefined) &&
|
|
@@ -110,220 +86,17 @@ export function translateCompiledFormula(compiled, rowDelta, colDelta, sourceOve
|
|
|
110
86
|
},
|
|
111
87
|
};
|
|
112
88
|
}
|
|
113
|
-
export function rewriteFormulaForStructuralTransform(source, ownerSheetName, targetSheetName, transform) {
|
|
114
|
-
const ast = parseFormula(source);
|
|
115
|
-
return serializeFormula(rewriteNodeForStructuralTransform(ast, ownerSheetName, targetSheetName, transform));
|
|
116
|
-
}
|
|
117
|
-
export function rewriteCompiledFormulaForStructuralTransform(compiled, ownerSheetName, targetSheetName, transform) {
|
|
118
|
-
const currentAst = compiled.astMatchesSource === false ? parseFormula(compiled.source) : compiled.ast;
|
|
119
|
-
const currentOptimizedAst = compiled.astMatchesSource === false ? currentAst : compiled.optimizedAst === compiled.ast ? currentAst : compiled.optimizedAst;
|
|
120
|
-
const rewrittenAst = rewriteNodeForStructuralTransform(currentAst, ownerSheetName, targetSheetName, transform);
|
|
121
|
-
const rewrittenOptimizedAst = currentOptimizedAst === currentAst
|
|
122
|
-
? rewrittenAst
|
|
123
|
-
: rewriteNodeForStructuralTransform(currentOptimizedAst, ownerSheetName, targetSheetName, transform);
|
|
124
|
-
const source = serializeFormula(rewrittenAst);
|
|
125
|
-
if (!nodeStructuralShapeEqual(currentOptimizedAst, rewrittenOptimizedAst)) {
|
|
126
|
-
return {
|
|
127
|
-
source,
|
|
128
|
-
compiled: compileFormulaAst(source, rewrittenOptimizedAst, {
|
|
129
|
-
originalAst: rewrittenAst,
|
|
130
|
-
symbolicNames: compiled.symbolicNames,
|
|
131
|
-
symbolicTables: compiled.symbolicTables,
|
|
132
|
-
symbolicSpills: compiled.symbolicSpills,
|
|
133
|
-
}),
|
|
134
|
-
reusedProgram: false,
|
|
135
|
-
};
|
|
136
|
-
}
|
|
137
|
-
return {
|
|
138
|
-
source,
|
|
139
|
-
compiled: {
|
|
140
|
-
...compiled,
|
|
141
|
-
source,
|
|
142
|
-
ast: rewrittenAst,
|
|
143
|
-
optimizedAst: rewrittenOptimizedAst,
|
|
144
|
-
astMatchesSource: true,
|
|
145
|
-
deps: compiled.deps.map((dependency) => rewriteQualifiedDependencyReference(dependency, ownerSheetName, targetSheetName, transform)),
|
|
146
|
-
symbolicRefs: compiled.symbolicRefs.map((ref) => rewriteQualifiedCellReference(ref, ownerSheetName, targetSheetName, transform)),
|
|
147
|
-
symbolicRanges: compiled.symbolicRanges.map((range) => rewriteQualifiedRangeReference(range, ownerSheetName, targetSheetName, transform)),
|
|
148
|
-
jsPlan: compiled.jsPlan.map((instruction) => rewriteJsPlanInstruction(instruction, ownerSheetName, targetSheetName, transform)),
|
|
149
|
-
...(compiled.parsedDeps
|
|
150
|
-
? {
|
|
151
|
-
parsedDeps: compiled.parsedDeps.map((dependency) => rewriteParsedDependencyReference(dependency, ownerSheetName, targetSheetName, transform)),
|
|
152
|
-
}
|
|
153
|
-
: {}),
|
|
154
|
-
...(compiled.parsedSymbolicRefs
|
|
155
|
-
? {
|
|
156
|
-
parsedSymbolicRefs: compiled.parsedSymbolicRefs.map((ref) => rewriteParsedCellReference(ref, ownerSheetName, targetSheetName, transform)),
|
|
157
|
-
}
|
|
158
|
-
: {}),
|
|
159
|
-
...(compiled.parsedSymbolicRanges
|
|
160
|
-
? {
|
|
161
|
-
parsedSymbolicRanges: compiled.parsedSymbolicRanges.map((range) => rewriteParsedRangeReference(range, ownerSheetName, targetSheetName, transform)),
|
|
162
|
-
}
|
|
163
|
-
: {}),
|
|
164
|
-
},
|
|
165
|
-
reusedProgram: true,
|
|
166
|
-
};
|
|
167
|
-
}
|
|
168
89
|
export function renameFormulaSheetReferences(source, oldSheetName, newSheetName) {
|
|
169
|
-
|
|
170
|
-
return serializeFormula(renameNodeSheetReferences(ast, oldSheetName, newSheetName));
|
|
90
|
+
return renameFormulaSheetReferencesImpl(source, oldSheetName, newSheetName);
|
|
171
91
|
}
|
|
172
92
|
export function renameCompiledFormulaSheetReferences(compiled, oldSheetName, newSheetName) {
|
|
173
|
-
|
|
174
|
-
const currentOptimizedAst = compiled.astMatchesSource === false ? currentAst : compiled.optimizedAst === compiled.ast ? currentAst : compiled.optimizedAst;
|
|
175
|
-
const renamedAst = renameNodeSheetReferences(currentAst, oldSheetName, newSheetName);
|
|
176
|
-
const renamedOptimizedAst = currentOptimizedAst === currentAst ? renamedAst : renameNodeSheetReferences(currentOptimizedAst, oldSheetName, newSheetName);
|
|
177
|
-
const source = serializeFormula(renamedAst);
|
|
178
|
-
return {
|
|
179
|
-
source,
|
|
180
|
-
compiled: {
|
|
181
|
-
...compiled,
|
|
182
|
-
source,
|
|
183
|
-
ast: renamedAst,
|
|
184
|
-
optimizedAst: renamedOptimizedAst,
|
|
185
|
-
astMatchesSource: true,
|
|
186
|
-
deps: compiled.deps.map((dependency) => renameQualifiedReferenceSheet(dependency, oldSheetName, newSheetName)),
|
|
187
|
-
...(compiled.parsedDeps
|
|
188
|
-
? {
|
|
189
|
-
parsedDeps: compiled.parsedDeps.map((dependency) => renameParsedDependencySheet(dependency, oldSheetName, newSheetName)),
|
|
190
|
-
}
|
|
191
|
-
: {}),
|
|
192
|
-
jsPlan: renameJsPlanSheetReferences(compiled.jsPlan, oldSheetName, newSheetName),
|
|
193
|
-
symbolicRefs: compiled.symbolicRefs.map((reference) => renameQualifiedReferenceSheet(reference, oldSheetName, newSheetName)),
|
|
194
|
-
...(compiled.parsedSymbolicRefs
|
|
195
|
-
? {
|
|
196
|
-
parsedSymbolicRefs: compiled.parsedSymbolicRefs.map((reference) => renameParsedCellReferenceSheet(reference, oldSheetName, newSheetName)),
|
|
197
|
-
}
|
|
198
|
-
: {}),
|
|
199
|
-
symbolicRanges: compiled.symbolicRanges.map((reference) => renameQualifiedReferenceSheet(reference, oldSheetName, newSheetName)),
|
|
200
|
-
...(compiled.parsedSymbolicRanges
|
|
201
|
-
? {
|
|
202
|
-
parsedSymbolicRanges: compiled.parsedSymbolicRanges.map((reference) => renameParsedRangeReferenceSheet(reference, oldSheetName, newSheetName)),
|
|
203
|
-
}
|
|
204
|
-
: {}),
|
|
205
|
-
},
|
|
206
|
-
reusedProgram: true,
|
|
207
|
-
};
|
|
208
|
-
}
|
|
209
|
-
function renameArraySheetReferences(values, rename) {
|
|
210
|
-
let changed = false;
|
|
211
|
-
const next = values.map((value) => {
|
|
212
|
-
const renamed = rename(value);
|
|
213
|
-
if (renamed !== value) {
|
|
214
|
-
changed = true;
|
|
215
|
-
}
|
|
216
|
-
return renamed;
|
|
217
|
-
});
|
|
218
|
-
return { values: next, changed };
|
|
93
|
+
return renameCompiledFormulaSheetReferencesImpl(compiled, oldSheetName, newSheetName);
|
|
219
94
|
}
|
|
220
95
|
export function renameCompiledFormulaSheetReferenceMetadata(compiled, oldSheetName, newSheetName) {
|
|
221
|
-
|
|
222
|
-
const symbolicRefs = renameArraySheetReferences(compiled.symbolicRefs, (reference) => renameQualifiedReferenceSheet(reference, oldSheetName, newSheetName));
|
|
223
|
-
const symbolicRanges = renameArraySheetReferences(compiled.symbolicRanges, (reference) => renameQualifiedReferenceSheet(reference, oldSheetName, newSheetName));
|
|
224
|
-
const parsedDeps = compiled.parsedDeps
|
|
225
|
-
? renameArraySheetReferences(compiled.parsedDeps, (dependency) => renameParsedDependencySheet(dependency, oldSheetName, newSheetName))
|
|
226
|
-
: undefined;
|
|
227
|
-
const parsedSymbolicRefs = compiled.parsedSymbolicRefs
|
|
228
|
-
? renameArraySheetReferences(compiled.parsedSymbolicRefs, (reference) => renameParsedCellReferenceSheet(reference, oldSheetName, newSheetName))
|
|
229
|
-
: undefined;
|
|
230
|
-
const parsedSymbolicRanges = compiled.parsedSymbolicRanges
|
|
231
|
-
? renameArraySheetReferences(compiled.parsedSymbolicRanges, (reference) => renameParsedRangeReferenceSheet(reference, oldSheetName, newSheetName))
|
|
232
|
-
: undefined;
|
|
233
|
-
const jsPlan = renameJsPlanSheetReferences(compiled.jsPlan, oldSheetName, newSheetName);
|
|
234
|
-
return {
|
|
235
|
-
compiled: {
|
|
236
|
-
...compiled,
|
|
237
|
-
astMatchesSource: false,
|
|
238
|
-
deps: deps.values,
|
|
239
|
-
...(parsedDeps ? { parsedDeps: parsedDeps.values } : {}),
|
|
240
|
-
jsPlan,
|
|
241
|
-
symbolicRefs: symbolicRefs.values,
|
|
242
|
-
...(parsedSymbolicRefs ? { parsedSymbolicRefs: parsedSymbolicRefs.values } : {}),
|
|
243
|
-
symbolicRanges: symbolicRanges.values,
|
|
244
|
-
...(parsedSymbolicRanges ? { parsedSymbolicRanges: parsedSymbolicRanges.values } : {}),
|
|
245
|
-
},
|
|
246
|
-
sourceChanged: deps.changed ||
|
|
247
|
-
symbolicRefs.changed ||
|
|
248
|
-
symbolicRanges.changed ||
|
|
249
|
-
(parsedDeps?.changed ?? false) ||
|
|
250
|
-
(parsedSymbolicRefs?.changed ?? false) ||
|
|
251
|
-
(parsedSymbolicRanges?.changed ?? false),
|
|
252
|
-
};
|
|
96
|
+
return renameCompiledFormulaSheetReferenceMetadataImpl(compiled, oldSheetName, newSheetName);
|
|
253
97
|
}
|
|
254
98
|
export function renameCompiledFormulaSheetReferenceMetadataInPlace(compiled, oldSheetName, newSheetName) {
|
|
255
|
-
|
|
256
|
-
const renameStringArrayInPlace = (values) => {
|
|
257
|
-
for (let index = 0; index < values.length; index += 1) {
|
|
258
|
-
const value = values[index];
|
|
259
|
-
const renamed = renameQualifiedReferenceSheet(value, oldSheetName, newSheetName);
|
|
260
|
-
if (renamed !== value) {
|
|
261
|
-
values[index] = renamed;
|
|
262
|
-
sourceChanged = true;
|
|
263
|
-
}
|
|
264
|
-
}
|
|
265
|
-
};
|
|
266
|
-
renameStringArrayInPlace(compiled.deps);
|
|
267
|
-
renameStringArrayInPlace(compiled.symbolicRefs);
|
|
268
|
-
renameStringArrayInPlace(compiled.symbolicRanges);
|
|
269
|
-
compiled.parsedDeps?.forEach((dependency) => {
|
|
270
|
-
const previousSheetName = dependency.sheetName;
|
|
271
|
-
if (previousSheetName === oldSheetName) {
|
|
272
|
-
dependency.sheetName = newSheetName;
|
|
273
|
-
sourceChanged = true;
|
|
274
|
-
}
|
|
275
|
-
});
|
|
276
|
-
compiled.parsedSymbolicRefs?.forEach((reference) => {
|
|
277
|
-
if (reference.sheetName === oldSheetName) {
|
|
278
|
-
reference.sheetName = newSheetName;
|
|
279
|
-
sourceChanged = true;
|
|
280
|
-
}
|
|
281
|
-
});
|
|
282
|
-
compiled.parsedSymbolicRanges?.forEach((reference) => {
|
|
283
|
-
if (reference.sheetName === oldSheetName) {
|
|
284
|
-
reference.sheetName = newSheetName;
|
|
285
|
-
sourceChanged = true;
|
|
286
|
-
}
|
|
287
|
-
});
|
|
288
|
-
if (compiled.jsPlan.length > 0) {
|
|
289
|
-
compiled.jsPlan = renameJsPlanSheetReferences(compiled.jsPlan, oldSheetName, newSheetName);
|
|
290
|
-
}
|
|
291
|
-
if (sourceChanged) {
|
|
292
|
-
compiled.astMatchesSource = false;
|
|
293
|
-
}
|
|
294
|
-
return sourceChanged;
|
|
295
|
-
}
|
|
296
|
-
export function rewriteAddressForStructuralTransform(address, transform) {
|
|
297
|
-
const parsed = parseCellReferenceParts(address);
|
|
298
|
-
if (!parsed) {
|
|
299
|
-
throw new Error(`Invalid cell reference '${address}'`);
|
|
300
|
-
}
|
|
301
|
-
const nextRow = transform.axis === 'row' ? mapPointIndex(parsed.row, transform) : parsed.row;
|
|
302
|
-
const nextCol = transform.axis === 'column' ? mapPointIndex(parsed.col, transform) : parsed.col;
|
|
303
|
-
if (nextRow === undefined || nextCol === undefined) {
|
|
304
|
-
return undefined;
|
|
305
|
-
}
|
|
306
|
-
return formatCellReference(parsed, nextRow, nextCol);
|
|
307
|
-
}
|
|
308
|
-
export function rewriteRangeForStructuralTransform(startAddress, endAddress, transform) {
|
|
309
|
-
const start = parseCellReferenceParts(startAddress);
|
|
310
|
-
const end = parseCellReferenceParts(endAddress);
|
|
311
|
-
if (!start || !end) {
|
|
312
|
-
throw new Error(`Invalid range reference '${startAddress}:${endAddress}'`);
|
|
313
|
-
}
|
|
314
|
-
const nextRows = transform.axis === 'row'
|
|
315
|
-
? mapInterval(Math.min(start.row, end.row), Math.max(start.row, end.row), transform)
|
|
316
|
-
: { start: Math.min(start.row, end.row), end: Math.max(start.row, end.row) };
|
|
317
|
-
const nextCols = transform.axis === 'column'
|
|
318
|
-
? mapInterval(Math.min(start.col, end.col), Math.max(start.col, end.col), transform)
|
|
319
|
-
: { start: Math.min(start.col, end.col), end: Math.max(start.col, end.col) };
|
|
320
|
-
if (!nextRows || !nextCols) {
|
|
321
|
-
return undefined;
|
|
322
|
-
}
|
|
323
|
-
return {
|
|
324
|
-
startAddress: formatCellReference(start, nextRows.start, nextCols.start),
|
|
325
|
-
endAddress: formatCellReference(end, nextRows.end, nextCols.end),
|
|
326
|
-
};
|
|
99
|
+
return renameCompiledFormulaSheetReferenceMetadataInPlaceImpl(compiled, oldSheetName, newSheetName);
|
|
327
100
|
}
|
|
328
101
|
function translateNode(node, rowDelta, colDelta) {
|
|
329
102
|
switch (node.kind) {
|
|
@@ -392,754 +165,6 @@ function translateNode(node, rowDelta, colDelta) {
|
|
|
392
165
|
};
|
|
393
166
|
}
|
|
394
167
|
}
|
|
395
|
-
function buildRelativeFormulaTemplateKeyInternal(node, ownerRow, ownerCol) {
|
|
396
|
-
switch (node.kind) {
|
|
397
|
-
case 'NumberLiteral':
|
|
398
|
-
return `n:${node.value}`;
|
|
399
|
-
case 'BooleanLiteral':
|
|
400
|
-
return node.value ? 'b:1' : 'b:0';
|
|
401
|
-
case 'StringLiteral':
|
|
402
|
-
return `s:${JSON.stringify(node.value)}`;
|
|
403
|
-
case 'ErrorLiteral':
|
|
404
|
-
return `e:${node.code}`;
|
|
405
|
-
case 'NameRef':
|
|
406
|
-
return `name:${node.name}`;
|
|
407
|
-
case 'StructuredRef':
|
|
408
|
-
return `table:${node.tableName}[${node.columnName}]`;
|
|
409
|
-
case 'CellRef':
|
|
410
|
-
return `cell:${templateSheetKey(node.sheetName)}:${buildRelativeCellReferenceKey(node.ref, ownerRow, ownerCol)}`;
|
|
411
|
-
case 'SpillRef':
|
|
412
|
-
return `spill:${templateSheetKey(node.sheetName)}:${buildRelativeCellReferenceKey(node.ref, ownerRow, ownerCol)}`;
|
|
413
|
-
case 'ColumnRef':
|
|
414
|
-
return `col:${templateSheetKey(node.sheetName)}:${buildRelativeAxisReferenceKey(node.ref, ownerCol, 'column')}`;
|
|
415
|
-
case 'RowRef':
|
|
416
|
-
return `row:${templateSheetKey(node.sheetName)}:${buildRelativeAxisReferenceKey(node.ref, ownerRow, 'row')}`;
|
|
417
|
-
case 'RangeRef':
|
|
418
|
-
return `range:${node.refKind}:${templateSheetKey(node.sheetName)}:${buildRelativeRangeReferenceKey(node, ownerRow, ownerCol)}`;
|
|
419
|
-
case 'UnaryExpr':
|
|
420
|
-
return `unary:${node.operator}:${buildRelativeFormulaTemplateKeyInternal(node.argument, ownerRow, ownerCol)}`;
|
|
421
|
-
case 'BinaryExpr':
|
|
422
|
-
return `binary:${node.operator}:${buildRelativeFormulaTemplateKeyInternal(node.left, ownerRow, ownerCol)}:${buildRelativeFormulaTemplateKeyInternal(node.right, ownerRow, ownerCol)}`;
|
|
423
|
-
case 'CallExpr':
|
|
424
|
-
return `call:${node.callee}:${node.args.map((arg) => buildRelativeFormulaTemplateKeyInternal(arg, ownerRow, ownerCol)).join('|')}`;
|
|
425
|
-
case 'InvokeExpr':
|
|
426
|
-
return `invoke:${buildRelativeFormulaTemplateKeyInternal(node.callee, ownerRow, ownerCol)}:${node.args.map((arg) => buildRelativeFormulaTemplateKeyInternal(arg, ownerRow, ownerCol)).join('|')}`;
|
|
427
|
-
}
|
|
428
|
-
}
|
|
429
|
-
function rewriteNodeForStructuralTransform(node, ownerSheetName, targetSheetName, transform) {
|
|
430
|
-
switch (node.kind) {
|
|
431
|
-
case 'NumberLiteral':
|
|
432
|
-
case 'BooleanLiteral':
|
|
433
|
-
case 'StringLiteral':
|
|
434
|
-
case 'ErrorLiteral':
|
|
435
|
-
case 'NameRef':
|
|
436
|
-
case 'StructuredRef':
|
|
437
|
-
return node;
|
|
438
|
-
case 'CellRef':
|
|
439
|
-
return rewriteCellLikeNode(node, ownerSheetName, targetSheetName, transform);
|
|
440
|
-
case 'SpillRef':
|
|
441
|
-
return rewriteCellLikeNode(node, ownerSheetName, targetSheetName, transform);
|
|
442
|
-
case 'ColumnRef':
|
|
443
|
-
if (!targetsSheet(node.sheetName, ownerSheetName, targetSheetName) || transform.axis !== 'column') {
|
|
444
|
-
return node;
|
|
445
|
-
}
|
|
446
|
-
return rewriteAxisNode(node, transform);
|
|
447
|
-
case 'RowRef':
|
|
448
|
-
if (!targetsSheet(node.sheetName, ownerSheetName, targetSheetName) || transform.axis !== 'row') {
|
|
449
|
-
return node;
|
|
450
|
-
}
|
|
451
|
-
return rewriteAxisNode(node, transform);
|
|
452
|
-
case 'RangeRef':
|
|
453
|
-
return rewriteRangeNode(node, ownerSheetName, targetSheetName, transform);
|
|
454
|
-
case 'UnaryExpr':
|
|
455
|
-
return {
|
|
456
|
-
...node,
|
|
457
|
-
argument: rewriteNodeForStructuralTransform(node.argument, ownerSheetName, targetSheetName, transform),
|
|
458
|
-
};
|
|
459
|
-
case 'BinaryExpr':
|
|
460
|
-
return {
|
|
461
|
-
...node,
|
|
462
|
-
left: rewriteNodeForStructuralTransform(node.left, ownerSheetName, targetSheetName, transform),
|
|
463
|
-
right: rewriteNodeForStructuralTransform(node.right, ownerSheetName, targetSheetName, transform),
|
|
464
|
-
};
|
|
465
|
-
case 'CallExpr':
|
|
466
|
-
return {
|
|
467
|
-
...node,
|
|
468
|
-
args: node.args.map((arg) => rewriteNodeForStructuralTransform(arg, ownerSheetName, targetSheetName, transform)),
|
|
469
|
-
};
|
|
470
|
-
case 'InvokeExpr':
|
|
471
|
-
return {
|
|
472
|
-
...node,
|
|
473
|
-
callee: rewriteNodeForStructuralTransform(node.callee, ownerSheetName, targetSheetName, transform),
|
|
474
|
-
args: node.args.map((arg) => rewriteNodeForStructuralTransform(arg, ownerSheetName, targetSheetName, transform)),
|
|
475
|
-
};
|
|
476
|
-
}
|
|
477
|
-
}
|
|
478
|
-
function templateSheetKey(sheetName) {
|
|
479
|
-
return sheetName === undefined ? '.' : JSON.stringify(sheetName);
|
|
480
|
-
}
|
|
481
|
-
function buildRelativeCellReferenceKey(ref, ownerRow, ownerCol) {
|
|
482
|
-
const parsed = parseCellReferenceParts(ref);
|
|
483
|
-
if (!parsed) {
|
|
484
|
-
return `invalid:${ref}`;
|
|
485
|
-
}
|
|
486
|
-
const colKey = parsed.colAbsolute ? `ac${parsed.col}` : `rc${parsed.col - ownerCol}`;
|
|
487
|
-
const rowKey = parsed.rowAbsolute ? `ar${parsed.row}` : `rr${parsed.row - ownerRow}`;
|
|
488
|
-
return `${colKey}:${rowKey}`;
|
|
489
|
-
}
|
|
490
|
-
function buildRelativeAxisReferenceKey(ref, ownerIndex, kind) {
|
|
491
|
-
const parsed = parseAxisReferenceParts(ref, kind);
|
|
492
|
-
if (!parsed) {
|
|
493
|
-
return `invalid:${ref}`;
|
|
494
|
-
}
|
|
495
|
-
return parsed.absolute ? `a${parsed.index}` : `r${parsed.index - ownerIndex}`;
|
|
496
|
-
}
|
|
497
|
-
function buildRelativeRangeReferenceKey(node, ownerRow, ownerCol) {
|
|
498
|
-
switch (node.refKind) {
|
|
499
|
-
case 'cells':
|
|
500
|
-
return `${buildRelativeCellReferenceKey(node.start, ownerRow, ownerCol)}:${buildRelativeCellReferenceKey(node.end, ownerRow, ownerCol)}`;
|
|
501
|
-
case 'rows':
|
|
502
|
-
return `${buildRelativeAxisReferenceKey(node.start, ownerRow, 'row')}:${buildRelativeAxisReferenceKey(node.end, ownerRow, 'row')}`;
|
|
503
|
-
case 'cols':
|
|
504
|
-
return `${buildRelativeAxisReferenceKey(node.start, ownerCol, 'column')}:${buildRelativeAxisReferenceKey(node.end, ownerCol, 'column')}`;
|
|
505
|
-
}
|
|
506
|
-
}
|
|
507
|
-
function nodeStructuralShapeEqual(left, right) {
|
|
508
|
-
if (left.kind !== right.kind) {
|
|
509
|
-
return false;
|
|
510
|
-
}
|
|
511
|
-
switch (left.kind) {
|
|
512
|
-
case 'NumberLiteral':
|
|
513
|
-
return right.kind === 'NumberLiteral' && left.value === right.value;
|
|
514
|
-
case 'BooleanLiteral':
|
|
515
|
-
return right.kind === 'BooleanLiteral' && left.value === right.value;
|
|
516
|
-
case 'StringLiteral':
|
|
517
|
-
return right.kind === 'StringLiteral' && left.value === right.value;
|
|
518
|
-
case 'ErrorLiteral':
|
|
519
|
-
return right.kind === 'ErrorLiteral' && left.code === right.code;
|
|
520
|
-
case 'NameRef':
|
|
521
|
-
return right.kind === 'NameRef' && left.name === right.name;
|
|
522
|
-
case 'StructuredRef':
|
|
523
|
-
return right.kind === 'StructuredRef' && left.tableName === right.tableName && left.columnName === right.columnName;
|
|
524
|
-
case 'CellRef':
|
|
525
|
-
case 'SpillRef':
|
|
526
|
-
case 'ColumnRef':
|
|
527
|
-
case 'RowRef':
|
|
528
|
-
return true;
|
|
529
|
-
case 'RangeRef':
|
|
530
|
-
return right.kind === 'RangeRef' && left.refKind === right.refKind;
|
|
531
|
-
case 'UnaryExpr':
|
|
532
|
-
return right.kind === 'UnaryExpr' && left.operator === right.operator && nodeStructuralShapeEqual(left.argument, right.argument);
|
|
533
|
-
case 'BinaryExpr':
|
|
534
|
-
return (right.kind === 'BinaryExpr' &&
|
|
535
|
-
left.operator === right.operator &&
|
|
536
|
-
nodeStructuralShapeEqual(left.left, right.left) &&
|
|
537
|
-
nodeStructuralShapeEqual(left.right, right.right));
|
|
538
|
-
case 'CallExpr':
|
|
539
|
-
return (right.kind === 'CallExpr' &&
|
|
540
|
-
left.callee === right.callee &&
|
|
541
|
-
left.args.length === right.args.length &&
|
|
542
|
-
left.args.every((arg, index) => nodeStructuralShapeEqual(arg, right.args[index])));
|
|
543
|
-
case 'InvokeExpr':
|
|
544
|
-
return (right.kind === 'InvokeExpr' &&
|
|
545
|
-
left.args.length === right.args.length &&
|
|
546
|
-
nodeStructuralShapeEqual(left.callee, right.callee) &&
|
|
547
|
-
left.args.every((arg, index) => nodeStructuralShapeEqual(arg, right.args[index])));
|
|
548
|
-
}
|
|
549
|
-
}
|
|
550
|
-
function renameNodeSheetReferences(node, oldSheetName, newSheetName) {
|
|
551
|
-
switch (node.kind) {
|
|
552
|
-
case 'NumberLiteral':
|
|
553
|
-
case 'BooleanLiteral':
|
|
554
|
-
case 'StringLiteral':
|
|
555
|
-
case 'ErrorLiteral':
|
|
556
|
-
case 'NameRef':
|
|
557
|
-
case 'StructuredRef':
|
|
558
|
-
return node;
|
|
559
|
-
case 'CellRef':
|
|
560
|
-
case 'SpillRef':
|
|
561
|
-
case 'RowRef':
|
|
562
|
-
case 'ColumnRef':
|
|
563
|
-
case 'RangeRef':
|
|
564
|
-
return {
|
|
565
|
-
...node,
|
|
566
|
-
...(node.sheetName === oldSheetName ? { sheetName: newSheetName } : {}),
|
|
567
|
-
};
|
|
568
|
-
case 'UnaryExpr':
|
|
569
|
-
return {
|
|
570
|
-
...node,
|
|
571
|
-
argument: renameNodeSheetReferences(node.argument, oldSheetName, newSheetName),
|
|
572
|
-
};
|
|
573
|
-
case 'BinaryExpr':
|
|
574
|
-
return {
|
|
575
|
-
...node,
|
|
576
|
-
left: renameNodeSheetReferences(node.left, oldSheetName, newSheetName),
|
|
577
|
-
right: renameNodeSheetReferences(node.right, oldSheetName, newSheetName),
|
|
578
|
-
};
|
|
579
|
-
case 'CallExpr':
|
|
580
|
-
return {
|
|
581
|
-
...node,
|
|
582
|
-
args: node.args.map((arg) => renameNodeSheetReferences(arg, oldSheetName, newSheetName)),
|
|
583
|
-
};
|
|
584
|
-
case 'InvokeExpr':
|
|
585
|
-
return {
|
|
586
|
-
...node,
|
|
587
|
-
callee: renameNodeSheetReferences(node.callee, oldSheetName, newSheetName),
|
|
588
|
-
args: node.args.map((arg) => renameNodeSheetReferences(arg, oldSheetName, newSheetName)),
|
|
589
|
-
};
|
|
590
|
-
}
|
|
591
|
-
}
|
|
592
|
-
function renameQualifiedReferenceSheet(reference, oldSheetName, newSheetName) {
|
|
593
|
-
const oldPrefix = `${quoteSheetNameIfNeeded(oldSheetName)}!`;
|
|
594
|
-
if (!reference.startsWith(oldPrefix)) {
|
|
595
|
-
return reference;
|
|
596
|
-
}
|
|
597
|
-
return `${quoteSheetNameIfNeeded(newSheetName)}!${reference.slice(oldPrefix.length)}`;
|
|
598
|
-
}
|
|
599
|
-
function renameParsedCellReferenceSheet(reference, oldSheetName, newSheetName) {
|
|
600
|
-
return reference.sheetName === oldSheetName ? { ...reference, sheetName: newSheetName } : reference;
|
|
601
|
-
}
|
|
602
|
-
function renameParsedRangeReferenceSheet(reference, oldSheetName, newSheetName) {
|
|
603
|
-
return reference.sheetName === oldSheetName
|
|
604
|
-
? {
|
|
605
|
-
...reference,
|
|
606
|
-
sheetName: newSheetName,
|
|
607
|
-
address: formatQualifiedRangeReference(newSheetName, reference.startAddress, reference.endAddress),
|
|
608
|
-
}
|
|
609
|
-
: reference;
|
|
610
|
-
}
|
|
611
|
-
function renameParsedDependencySheet(dependency, oldSheetName, newSheetName) {
|
|
612
|
-
return dependency.kind === 'cell'
|
|
613
|
-
? renameParsedCellReferenceSheet(dependency, oldSheetName, newSheetName)
|
|
614
|
-
: renameParsedRangeReferenceSheet(dependency, oldSheetName, newSheetName);
|
|
615
|
-
}
|
|
616
|
-
function renameReferenceOperandSheet(operand, oldSheetName, newSheetName) {
|
|
617
|
-
return operand?.sheetName === oldSheetName ? { ...operand, sheetName: newSheetName } : operand;
|
|
618
|
-
}
|
|
619
|
-
function renameJsPlanSheetReferences(plan, oldSheetName, newSheetName) {
|
|
620
|
-
return plan.map((instruction) => {
|
|
621
|
-
switch (instruction.opcode) {
|
|
622
|
-
case 'push-cell':
|
|
623
|
-
case 'push-range':
|
|
624
|
-
case 'lookup-exact-match':
|
|
625
|
-
case 'lookup-approximate-match':
|
|
626
|
-
return instruction.sheetName === oldSheetName ? { ...instruction, sheetName: newSheetName } : instruction;
|
|
627
|
-
case 'push-lambda':
|
|
628
|
-
return { ...instruction, body: renameJsPlanSheetReferences(instruction.body, oldSheetName, newSheetName) };
|
|
629
|
-
case 'call':
|
|
630
|
-
return instruction.argRefs
|
|
631
|
-
? {
|
|
632
|
-
...instruction,
|
|
633
|
-
argRefs: instruction.argRefs.map((operand) => renameReferenceOperandSheet(operand, oldSheetName, newSheetName)),
|
|
634
|
-
}
|
|
635
|
-
: instruction;
|
|
636
|
-
case 'begin-scope':
|
|
637
|
-
case 'binary':
|
|
638
|
-
case 'bind-name':
|
|
639
|
-
case 'end-scope':
|
|
640
|
-
case 'invoke':
|
|
641
|
-
case 'jump':
|
|
642
|
-
case 'jump-if-false':
|
|
643
|
-
case 'push-boolean':
|
|
644
|
-
case 'push-error':
|
|
645
|
-
case 'push-name':
|
|
646
|
-
case 'push-number':
|
|
647
|
-
case 'push-string':
|
|
648
|
-
case 'return':
|
|
649
|
-
case 'unary':
|
|
650
|
-
return instruction;
|
|
651
|
-
default:
|
|
652
|
-
return instruction;
|
|
653
|
-
}
|
|
654
|
-
});
|
|
655
|
-
}
|
|
656
|
-
function rewriteCellLikeNode(node, ownerSheetName, targetSheetName, transform) {
|
|
657
|
-
if (!targetsSheet(node.sheetName, ownerSheetName, targetSheetName)) {
|
|
658
|
-
return node;
|
|
659
|
-
}
|
|
660
|
-
const parsed = parseCellReferenceParts(node.ref);
|
|
661
|
-
if (!parsed) {
|
|
662
|
-
return { kind: 'ErrorLiteral', code: ErrorCode.Ref };
|
|
663
|
-
}
|
|
664
|
-
const nextRow = transform.axis === 'row' ? mapPointIndex(parsed.row, transform) : parsed.row;
|
|
665
|
-
const nextCol = transform.axis === 'column' ? mapPointIndex(parsed.col, transform) : parsed.col;
|
|
666
|
-
if (nextRow === undefined || nextCol === undefined) {
|
|
667
|
-
return { kind: 'ErrorLiteral', code: ErrorCode.Ref };
|
|
668
|
-
}
|
|
669
|
-
return {
|
|
670
|
-
...node,
|
|
671
|
-
ref: formatCellReference(parsed, nextRow, nextCol),
|
|
672
|
-
};
|
|
673
|
-
}
|
|
674
|
-
function rewriteAxisNode(node, transform) {
|
|
675
|
-
const parsed = parseAxisReferenceParts(node.ref, node.kind === 'RowRef' ? 'row' : 'column');
|
|
676
|
-
if (!parsed) {
|
|
677
|
-
return { kind: 'ErrorLiteral', code: ErrorCode.Ref };
|
|
678
|
-
}
|
|
679
|
-
const nextIndex = mapPointIndex(parsed.index, transform);
|
|
680
|
-
if (nextIndex === undefined) {
|
|
681
|
-
return { kind: 'ErrorLiteral', code: ErrorCode.Ref };
|
|
682
|
-
}
|
|
683
|
-
return {
|
|
684
|
-
...node,
|
|
685
|
-
ref: formatAxisReference(parsed.absolute, nextIndex, node.kind === 'RowRef' ? 'row' : 'column'),
|
|
686
|
-
};
|
|
687
|
-
}
|
|
688
|
-
function rewriteRangeNode(node, ownerSheetName, targetSheetName, transform) {
|
|
689
|
-
if (!targetsSheet(node.sheetName, ownerSheetName, targetSheetName)) {
|
|
690
|
-
return node;
|
|
691
|
-
}
|
|
692
|
-
if ((node.refKind === 'rows' && transform.axis === 'column') || (node.refKind === 'cols' && transform.axis === 'row')) {
|
|
693
|
-
return node;
|
|
694
|
-
}
|
|
695
|
-
if (node.refKind === 'cells') {
|
|
696
|
-
const start = parseCellReferenceParts(node.start);
|
|
697
|
-
const end = parseCellReferenceParts(node.end);
|
|
698
|
-
if (!start || !end) {
|
|
699
|
-
return { kind: 'ErrorLiteral', code: ErrorCode.Ref };
|
|
700
|
-
}
|
|
701
|
-
const nextRows = transform.axis === 'row'
|
|
702
|
-
? mapInterval(Math.min(start.row, end.row), Math.max(start.row, end.row), transform)
|
|
703
|
-
: { start: Math.min(start.row, end.row), end: Math.max(start.row, end.row) };
|
|
704
|
-
const nextCols = transform.axis === 'column'
|
|
705
|
-
? mapInterval(Math.min(start.col, end.col), Math.max(start.col, end.col), transform)
|
|
706
|
-
: { start: Math.min(start.col, end.col), end: Math.max(start.col, end.col) };
|
|
707
|
-
if (!nextRows || !nextCols) {
|
|
708
|
-
return { kind: 'ErrorLiteral', code: ErrorCode.Ref };
|
|
709
|
-
}
|
|
710
|
-
return {
|
|
711
|
-
...node,
|
|
712
|
-
start: formatCellReference(start, nextRows.start, nextCols.start),
|
|
713
|
-
end: formatCellReference(end, nextRows.end, nextCols.end),
|
|
714
|
-
};
|
|
715
|
-
}
|
|
716
|
-
const start = parseAxisReferenceParts(node.start, node.refKind === 'rows' ? 'row' : 'column');
|
|
717
|
-
const end = parseAxisReferenceParts(node.end, node.refKind === 'rows' ? 'row' : 'column');
|
|
718
|
-
if (!start || !end) {
|
|
719
|
-
return { kind: 'ErrorLiteral', code: ErrorCode.Ref };
|
|
720
|
-
}
|
|
721
|
-
const nextInterval = mapInterval(Math.min(start.index, end.index), Math.max(start.index, end.index), transform);
|
|
722
|
-
if (!nextInterval) {
|
|
723
|
-
return { kind: 'ErrorLiteral', code: ErrorCode.Ref };
|
|
724
|
-
}
|
|
725
|
-
return {
|
|
726
|
-
...node,
|
|
727
|
-
start: formatAxisReference(start.absolute, nextInterval.start, node.refKind === 'rows' ? 'row' : 'column'),
|
|
728
|
-
end: formatAxisReference(end.absolute, nextInterval.end, node.refKind === 'rows' ? 'row' : 'column'),
|
|
729
|
-
};
|
|
730
|
-
}
|
|
731
|
-
function rewriteParsedCellReference(reference, ownerSheetName, targetSheetName, transform) {
|
|
732
|
-
const sheetName = reference.sheetName ?? ownerSheetName;
|
|
733
|
-
if (sheetName !== targetSheetName) {
|
|
734
|
-
return reference;
|
|
735
|
-
}
|
|
736
|
-
const nextAddress = rewriteAddressForStructuralTransform(reference.address, transform);
|
|
737
|
-
if (!nextAddress) {
|
|
738
|
-
return reference;
|
|
739
|
-
}
|
|
740
|
-
const parsed = parseCellAddress(nextAddress, sheetName);
|
|
741
|
-
return {
|
|
742
|
-
...reference,
|
|
743
|
-
address: parsed.text,
|
|
744
|
-
...(reference.sheetName !== undefined ? { sheetName: parsed.sheetName } : {}),
|
|
745
|
-
...(reference.row !== undefined ? { row: parsed.row } : {}),
|
|
746
|
-
...(reference.col !== undefined ? { col: parsed.col } : {}),
|
|
747
|
-
};
|
|
748
|
-
}
|
|
749
|
-
function rewriteParsedRangeReference(reference, ownerSheetName, targetSheetName, transform) {
|
|
750
|
-
const explicitSheetName = reference.sheetName;
|
|
751
|
-
if (!targetsSheet(explicitSheetName, ownerSheetName, targetSheetName)) {
|
|
752
|
-
return reference;
|
|
753
|
-
}
|
|
754
|
-
const nextRange = rewriteRangeAddressForStructuralTransform(parseRangeAddress(formatQualifiedRangeReference(explicitSheetName, reference.startAddress, reference.endAddress)), transform);
|
|
755
|
-
if (!nextRange) {
|
|
756
|
-
return reference;
|
|
757
|
-
}
|
|
758
|
-
const bounds = nextRange.kind === 'cells'
|
|
759
|
-
? {
|
|
760
|
-
startRow: nextRange.start.row,
|
|
761
|
-
endRow: nextRange.end.row,
|
|
762
|
-
startCol: nextRange.start.col,
|
|
763
|
-
endCol: nextRange.end.col,
|
|
764
|
-
}
|
|
765
|
-
: nextRange.kind === 'rows'
|
|
766
|
-
? {
|
|
767
|
-
startRow: nextRange.start.row,
|
|
768
|
-
endRow: nextRange.end.row,
|
|
769
|
-
startCol: 0,
|
|
770
|
-
endCol: 0,
|
|
771
|
-
}
|
|
772
|
-
: {
|
|
773
|
-
startRow: 0,
|
|
774
|
-
endRow: 0,
|
|
775
|
-
startCol: nextRange.start.col,
|
|
776
|
-
endCol: nextRange.end.col,
|
|
777
|
-
};
|
|
778
|
-
return {
|
|
779
|
-
...reference,
|
|
780
|
-
address: formatQualifiedRangeReference(explicitSheetName, nextRange.start.text, nextRange.end.text),
|
|
781
|
-
refKind: nextRange.kind,
|
|
782
|
-
startAddress: nextRange.start.text,
|
|
783
|
-
endAddress: nextRange.end.text,
|
|
784
|
-
...bounds,
|
|
785
|
-
};
|
|
786
|
-
}
|
|
787
|
-
function rewriteParsedDependencyReference(reference, ownerSheetName, targetSheetName, transform) {
|
|
788
|
-
return reference.kind === 'cell'
|
|
789
|
-
? rewriteParsedCellReference(reference, ownerSheetName, targetSheetName, transform)
|
|
790
|
-
: rewriteParsedRangeReference(reference, ownerSheetName, targetSheetName, transform);
|
|
791
|
-
}
|
|
792
|
-
function translateParsedCellReference(reference, rowDelta, colDelta) {
|
|
793
|
-
const parts = reference.rowAbsolute !== undefined && reference.colAbsolute !== undefined && reference.row !== undefined && reference.col !== undefined
|
|
794
|
-
? {
|
|
795
|
-
row: reference.row,
|
|
796
|
-
col: reference.col,
|
|
797
|
-
rowAbsolute: reference.rowAbsolute,
|
|
798
|
-
colAbsolute: reference.colAbsolute,
|
|
799
|
-
}
|
|
800
|
-
: parseCellReferenceParts(reference.address);
|
|
801
|
-
if (!parts) {
|
|
802
|
-
return reference;
|
|
803
|
-
}
|
|
804
|
-
const nextRow = parts.rowAbsolute ? parts.row : parts.row + rowDelta;
|
|
805
|
-
const nextCol = parts.colAbsolute ? parts.col : parts.col + colDelta;
|
|
806
|
-
const nextLocalAddress = formatCellReference(parts, nextRow, nextCol);
|
|
807
|
-
const nextAddress = reference.explicitSheet || reference.sheetName !== undefined
|
|
808
|
-
? formatQualifiedCellReference(reference.sheetName, nextLocalAddress)
|
|
809
|
-
: nextLocalAddress;
|
|
810
|
-
return {
|
|
811
|
-
...reference,
|
|
812
|
-
address: nextAddress,
|
|
813
|
-
...(reference.sheetName !== undefined ? { sheetName: reference.sheetName } : {}),
|
|
814
|
-
...(reference.explicitSheet !== undefined ? { explicitSheet: reference.explicitSheet } : {}),
|
|
815
|
-
...(reference.row !== undefined ? { row: nextRow } : {}),
|
|
816
|
-
...(reference.col !== undefined ? { col: nextCol } : {}),
|
|
817
|
-
...(reference.rowAbsolute !== undefined ? { rowAbsolute: parts.rowAbsolute } : {}),
|
|
818
|
-
...(reference.colAbsolute !== undefined ? { colAbsolute: parts.colAbsolute } : {}),
|
|
819
|
-
};
|
|
820
|
-
}
|
|
821
|
-
function translateParsedRangeReference(reference, rowDelta, colDelta) {
|
|
822
|
-
const nextRange = translateParsedRangeReferenceInfo(reference, rowDelta, colDelta);
|
|
823
|
-
const bounds = nextRange.refKind === 'cells'
|
|
824
|
-
? {
|
|
825
|
-
startRow: nextRange.startRow,
|
|
826
|
-
endRow: nextRange.endRow,
|
|
827
|
-
startCol: nextRange.startCol,
|
|
828
|
-
endCol: nextRange.endCol,
|
|
829
|
-
}
|
|
830
|
-
: nextRange.refKind === 'rows'
|
|
831
|
-
? {
|
|
832
|
-
startRow: nextRange.startRow,
|
|
833
|
-
endRow: nextRange.endRow,
|
|
834
|
-
startCol: 0,
|
|
835
|
-
endCol: 0,
|
|
836
|
-
}
|
|
837
|
-
: {
|
|
838
|
-
startRow: 0,
|
|
839
|
-
endRow: 0,
|
|
840
|
-
startCol: nextRange.startCol,
|
|
841
|
-
endCol: nextRange.endCol,
|
|
842
|
-
};
|
|
843
|
-
return {
|
|
844
|
-
...reference,
|
|
845
|
-
address: formatParsedRangeReference(nextRange),
|
|
846
|
-
refKind: nextRange.refKind,
|
|
847
|
-
startAddress: nextRange.startAddress,
|
|
848
|
-
endAddress: nextRange.endAddress,
|
|
849
|
-
...bounds,
|
|
850
|
-
...(reference.explicitSheet !== undefined ? { explicitSheet: reference.explicitSheet } : {}),
|
|
851
|
-
};
|
|
852
|
-
}
|
|
853
|
-
function translateParsedDependencyReference(reference, rowDelta, colDelta) {
|
|
854
|
-
return reference.kind === 'cell'
|
|
855
|
-
? translateParsedCellReference(reference, rowDelta, colDelta)
|
|
856
|
-
: translateParsedRangeReference(reference, rowDelta, colDelta);
|
|
857
|
-
}
|
|
858
|
-
function translateQualifiedCellReference(raw, rowDelta, colDelta) {
|
|
859
|
-
const explicitlyQualified = raw.includes('!');
|
|
860
|
-
const parsed = parseCellAddress(raw);
|
|
861
|
-
const nextAddress = translateCellReference(parsed.text, rowDelta, colDelta);
|
|
862
|
-
return explicitlyQualified ? formatQualifiedCellReference(parsed.sheetName, nextAddress) : nextAddress;
|
|
863
|
-
}
|
|
864
|
-
function formatParsedCellReference(reference) {
|
|
865
|
-
const localAddress = formatParsedLocalCellReference(reference);
|
|
866
|
-
return reference.explicitSheet || reference.sheetName !== undefined
|
|
867
|
-
? formatQualifiedCellReference(reference.sheetName, localAddress)
|
|
868
|
-
: localAddress;
|
|
869
|
-
}
|
|
870
|
-
function formatParsedLocalCellReference(reference) {
|
|
871
|
-
const parts = reference.row !== undefined && reference.col !== undefined && reference.rowAbsolute !== undefined && reference.colAbsolute !== undefined
|
|
872
|
-
? {
|
|
873
|
-
row: reference.row,
|
|
874
|
-
col: reference.col,
|
|
875
|
-
rowAbsolute: reference.rowAbsolute,
|
|
876
|
-
colAbsolute: reference.colAbsolute,
|
|
877
|
-
}
|
|
878
|
-
: parseCellReferenceParts(reference.address);
|
|
879
|
-
if (!parts) {
|
|
880
|
-
return stripSheetQualifier(reference.address);
|
|
881
|
-
}
|
|
882
|
-
return formatCellReference(parts, parts.row, parts.col);
|
|
883
|
-
}
|
|
884
|
-
function formatParsedRangeReference(reference) {
|
|
885
|
-
return formatQualifiedRangeReference(reference.explicitSheet ? reference.sheetName : undefined, reference.startAddress, reference.endAddress);
|
|
886
|
-
}
|
|
887
|
-
function stripSheetQualifier(reference) {
|
|
888
|
-
const bang = reference.lastIndexOf('!');
|
|
889
|
-
return bang === -1 ? reference : reference.slice(bang + 1);
|
|
890
|
-
}
|
|
891
|
-
function translatedCellInstructionKey(sheetName, address) {
|
|
892
|
-
return `${sheetName ?? ''}\t${address}`;
|
|
893
|
-
}
|
|
894
|
-
function translatedRangeInstructionKey(sheetName, refKind, start, end) {
|
|
895
|
-
return `${sheetName ?? ''}\t${refKind}\t${start}\t${end}`;
|
|
896
|
-
}
|
|
897
|
-
function buildTranslatedCellReferenceMap(original, translated) {
|
|
898
|
-
const output = new Map();
|
|
899
|
-
if (!original || !translated || original.length !== translated.length) {
|
|
900
|
-
return output;
|
|
901
|
-
}
|
|
902
|
-
for (let index = 0; index < original.length; index += 1) {
|
|
903
|
-
const source = original[index];
|
|
904
|
-
const target = translated[index];
|
|
905
|
-
if (!source || !target) {
|
|
906
|
-
continue;
|
|
907
|
-
}
|
|
908
|
-
output.set(translatedCellInstructionKey(source.sheetName, formatParsedLocalCellReference(source)), target);
|
|
909
|
-
}
|
|
910
|
-
return output;
|
|
911
|
-
}
|
|
912
|
-
function buildTranslatedRangeReferenceMap(original, translated) {
|
|
913
|
-
const output = new Map();
|
|
914
|
-
if (!original || !translated || original.length !== translated.length) {
|
|
915
|
-
return output;
|
|
916
|
-
}
|
|
917
|
-
for (let index = 0; index < original.length; index += 1) {
|
|
918
|
-
const source = original[index];
|
|
919
|
-
const target = translated[index];
|
|
920
|
-
if (!source || !target) {
|
|
921
|
-
continue;
|
|
922
|
-
}
|
|
923
|
-
output.set(translatedRangeInstructionKey(source.sheetName, source.refKind, source.startAddress, source.endAddress), target);
|
|
924
|
-
}
|
|
925
|
-
return output;
|
|
926
|
-
}
|
|
927
|
-
function formatParsedDependencyReference(reference) {
|
|
928
|
-
return reference.kind === 'cell' ? formatParsedCellReference(reference) : formatParsedRangeReference(reference);
|
|
929
|
-
}
|
|
930
|
-
function translateQualifiedDependencyReference(raw, rowDelta, colDelta) {
|
|
931
|
-
if (!raw.includes(':')) {
|
|
932
|
-
return translateQualifiedCellReference(raw, rowDelta, colDelta);
|
|
933
|
-
}
|
|
934
|
-
return translateQualifiedRangeReference(raw, rowDelta, colDelta);
|
|
935
|
-
}
|
|
936
|
-
function translateQualifiedRangeReference(raw, rowDelta, colDelta) {
|
|
937
|
-
const explicitlyQualified = raw.includes('!');
|
|
938
|
-
const parsed = parseRangeAddress(raw);
|
|
939
|
-
const nextRange = translateRangeAddress(parsed, rowDelta, colDelta);
|
|
940
|
-
if (explicitlyQualified) {
|
|
941
|
-
return formatRangeAddress(nextRange);
|
|
942
|
-
}
|
|
943
|
-
return `${nextRange.start.text}:${nextRange.end.text}`;
|
|
944
|
-
}
|
|
945
|
-
function translateRangeAddress(range, rowDelta, colDelta) {
|
|
946
|
-
switch (range.kind) {
|
|
947
|
-
case 'cells': {
|
|
948
|
-
const startAddress = translateCellReference(range.start.text, rowDelta, colDelta);
|
|
949
|
-
const endAddress = translateCellReference(range.end.text, rowDelta, colDelta);
|
|
950
|
-
return parseRangeAddress(formatQualifiedRangeReference(range.sheetName, startAddress, endAddress));
|
|
951
|
-
}
|
|
952
|
-
case 'rows': {
|
|
953
|
-
const start = translateRowReference(range.start.text, rowDelta);
|
|
954
|
-
const end = translateRowReference(range.end.text, rowDelta);
|
|
955
|
-
return parseRangeAddress(formatQualifiedRangeReference(range.sheetName, start, end));
|
|
956
|
-
}
|
|
957
|
-
case 'cols': {
|
|
958
|
-
const start = translateColumnReference(range.start.text, colDelta);
|
|
959
|
-
const end = translateColumnReference(range.end.text, colDelta);
|
|
960
|
-
return parseRangeAddress(formatQualifiedRangeReference(range.sheetName, start, end));
|
|
961
|
-
}
|
|
962
|
-
}
|
|
963
|
-
}
|
|
964
|
-
function translateParsedRangeReferenceInfo(reference, rowDelta, colDelta) {
|
|
965
|
-
if (reference.refKind === 'cells') {
|
|
966
|
-
const startRow = (reference.startRowAbsolute ?? false) ? reference.startRow : reference.startRow + rowDelta;
|
|
967
|
-
const endRow = (reference.endRowAbsolute ?? false) ? reference.endRow : reference.endRow + rowDelta;
|
|
968
|
-
const startCol = (reference.startColAbsolute ?? false) ? reference.startCol : reference.startCol + colDelta;
|
|
969
|
-
const endCol = (reference.endColAbsolute ?? false) ? reference.endCol : reference.endCol + colDelta;
|
|
970
|
-
const startAddress = formatCellReference({
|
|
971
|
-
row: reference.startRow,
|
|
972
|
-
col: reference.startCol,
|
|
973
|
-
rowAbsolute: reference.startRowAbsolute ?? false,
|
|
974
|
-
colAbsolute: reference.startColAbsolute ?? false,
|
|
975
|
-
}, startRow, startCol);
|
|
976
|
-
const endAddress = formatCellReference({
|
|
977
|
-
row: reference.endRow,
|
|
978
|
-
col: reference.endCol,
|
|
979
|
-
rowAbsolute: reference.endRowAbsolute ?? false,
|
|
980
|
-
colAbsolute: reference.endColAbsolute ?? false,
|
|
981
|
-
}, endRow, endCol);
|
|
982
|
-
return {
|
|
983
|
-
...reference,
|
|
984
|
-
startAddress,
|
|
985
|
-
endAddress,
|
|
986
|
-
startRow,
|
|
987
|
-
endRow,
|
|
988
|
-
startCol,
|
|
989
|
-
endCol,
|
|
990
|
-
};
|
|
991
|
-
}
|
|
992
|
-
if (reference.refKind === 'rows') {
|
|
993
|
-
const startRow = (reference.startRowAbsolute ?? false) ? reference.startRow : reference.startRow + rowDelta;
|
|
994
|
-
const endRow = (reference.endRowAbsolute ?? false) ? reference.endRow : reference.endRow + rowDelta;
|
|
995
|
-
return {
|
|
996
|
-
...reference,
|
|
997
|
-
startAddress: formatAxisReference(reference.startRowAbsolute ?? false, startRow, 'row'),
|
|
998
|
-
endAddress: formatAxisReference(reference.endRowAbsolute ?? false, endRow, 'row'),
|
|
999
|
-
startRow,
|
|
1000
|
-
endRow,
|
|
1001
|
-
startCol: 0,
|
|
1002
|
-
endCol: 0,
|
|
1003
|
-
};
|
|
1004
|
-
}
|
|
1005
|
-
const startCol = (reference.startColAbsolute ?? false) ? reference.startCol : reference.startCol + colDelta;
|
|
1006
|
-
const endCol = (reference.endColAbsolute ?? false) ? reference.endCol : reference.endCol + colDelta;
|
|
1007
|
-
return {
|
|
1008
|
-
...reference,
|
|
1009
|
-
startAddress: formatAxisReference(reference.startColAbsolute ?? false, startCol, 'column'),
|
|
1010
|
-
endAddress: formatAxisReference(reference.endColAbsolute ?? false, endCol, 'column'),
|
|
1011
|
-
startRow: 0,
|
|
1012
|
-
endRow: 0,
|
|
1013
|
-
startCol,
|
|
1014
|
-
endCol,
|
|
1015
|
-
};
|
|
1016
|
-
}
|
|
1017
|
-
function rewriteQualifiedCellReference(raw, ownerSheetName, targetSheetName, transform) {
|
|
1018
|
-
const explicitlyQualified = raw.includes('!');
|
|
1019
|
-
const parsed = parseCellAddress(raw, ownerSheetName);
|
|
1020
|
-
if (parsed.sheetName !== targetSheetName) {
|
|
1021
|
-
return raw;
|
|
1022
|
-
}
|
|
1023
|
-
const nextAddress = rewriteAddressForStructuralTransform(parsed.text, transform);
|
|
1024
|
-
if (!nextAddress) {
|
|
1025
|
-
return raw;
|
|
1026
|
-
}
|
|
1027
|
-
return explicitlyQualified ? formatQualifiedCellReference(parsed.sheetName, nextAddress) : nextAddress;
|
|
1028
|
-
}
|
|
1029
|
-
function rewriteQualifiedDependencyReference(raw, ownerSheetName, targetSheetName, transform) {
|
|
1030
|
-
if (!raw.includes(':')) {
|
|
1031
|
-
return rewriteQualifiedCellReference(raw, ownerSheetName, targetSheetName, transform);
|
|
1032
|
-
}
|
|
1033
|
-
return rewriteQualifiedRangeReference(raw, ownerSheetName, targetSheetName, transform);
|
|
1034
|
-
}
|
|
1035
|
-
function rewriteQualifiedRangeReference(raw, ownerSheetName, targetSheetName, transform) {
|
|
1036
|
-
const explicitlyQualified = raw.includes('!');
|
|
1037
|
-
const parsed = parseRangeAddress(raw, ownerSheetName);
|
|
1038
|
-
const sheetName = parsed.sheetName ?? ownerSheetName;
|
|
1039
|
-
if (sheetName !== targetSheetName) {
|
|
1040
|
-
return raw;
|
|
1041
|
-
}
|
|
1042
|
-
const nextRange = rewriteRangeAddressForStructuralTransform(parsed, transform);
|
|
1043
|
-
if (!nextRange) {
|
|
1044
|
-
return raw;
|
|
1045
|
-
}
|
|
1046
|
-
if (explicitlyQualified) {
|
|
1047
|
-
return formatRangeAddress(nextRange);
|
|
1048
|
-
}
|
|
1049
|
-
return `${nextRange.start.text}:${nextRange.end.text}`;
|
|
1050
|
-
}
|
|
1051
|
-
function rewriteRangeAddressForStructuralTransform(range, transform) {
|
|
1052
|
-
switch (range.kind) {
|
|
1053
|
-
case 'cells': {
|
|
1054
|
-
const nextRange = rewriteRangeForStructuralTransform(range.start.text, range.end.text, transform);
|
|
1055
|
-
if (!nextRange) {
|
|
1056
|
-
return undefined;
|
|
1057
|
-
}
|
|
1058
|
-
return parseRangeAddress(formatQualifiedRangeReference(range.sheetName, nextRange.startAddress, nextRange.endAddress));
|
|
1059
|
-
}
|
|
1060
|
-
case 'rows':
|
|
1061
|
-
if (transform.axis !== 'row') {
|
|
1062
|
-
return range;
|
|
1063
|
-
}
|
|
1064
|
-
return rewriteAxisRangeAddress(range, transform);
|
|
1065
|
-
case 'cols':
|
|
1066
|
-
if (transform.axis !== 'column') {
|
|
1067
|
-
return range;
|
|
1068
|
-
}
|
|
1069
|
-
return rewriteAxisRangeAddress(range, transform);
|
|
1070
|
-
}
|
|
1071
|
-
}
|
|
1072
|
-
function rewriteAxisRangeAddress(range, transform) {
|
|
1073
|
-
const startIndex = range.kind === 'rows' ? range.start.row : range.start.col;
|
|
1074
|
-
const endIndex = range.kind === 'rows' ? range.end.row : range.end.col;
|
|
1075
|
-
const nextInterval = mapInterval(startIndex, endIndex, transform);
|
|
1076
|
-
if (!nextInterval) {
|
|
1077
|
-
return undefined;
|
|
1078
|
-
}
|
|
1079
|
-
const prefix = range.sheetName ? `${quoteSheetNameIfNeeded(range.sheetName)}!` : '';
|
|
1080
|
-
const startText = range.kind === 'rows' ? formatAxisReference(false, nextInterval.start, 'row') : formatAxisReference(false, nextInterval.start, 'column');
|
|
1081
|
-
const endText = range.kind === 'rows' ? formatAxisReference(false, nextInterval.end, 'row') : formatAxisReference(false, nextInterval.end, 'column');
|
|
1082
|
-
return parseRangeAddress(`${prefix}${startText}:${endText}`);
|
|
1083
|
-
}
|
|
1084
|
-
function rewriteJsPlanInstruction(instruction, ownerSheetName, targetSheetName, transform) {
|
|
1085
|
-
switch (instruction.opcode) {
|
|
1086
|
-
case 'push-cell':
|
|
1087
|
-
return {
|
|
1088
|
-
...instruction,
|
|
1089
|
-
address: rewriteReferenceOperandAddress(instruction.sheetName, instruction.address, ownerSheetName, targetSheetName, transform),
|
|
1090
|
-
};
|
|
1091
|
-
case 'push-range': {
|
|
1092
|
-
const nextRange = rewritePlanRangeInstruction(instruction.sheetName, instruction.start, instruction.end, instruction.refKind, ownerSheetName, targetSheetName, transform);
|
|
1093
|
-
return nextRange ? { ...instruction, ...nextRange } : instruction;
|
|
1094
|
-
}
|
|
1095
|
-
case 'lookup-exact-match':
|
|
1096
|
-
case 'lookup-approximate-match': {
|
|
1097
|
-
const nextRange = rewritePlanRangeInstruction(instruction.sheetName, instruction.start, instruction.end, instruction.refKind, ownerSheetName, targetSheetName, transform);
|
|
1098
|
-
if (!nextRange) {
|
|
1099
|
-
return instruction;
|
|
1100
|
-
}
|
|
1101
|
-
const parsed = parseRangeAddress(formatQualifiedRangeReference(instruction.sheetName, nextRange.start, nextRange.end));
|
|
1102
|
-
if (parsed.kind !== 'cells') {
|
|
1103
|
-
return instruction;
|
|
1104
|
-
}
|
|
1105
|
-
return {
|
|
1106
|
-
...instruction,
|
|
1107
|
-
...nextRange,
|
|
1108
|
-
startRow: parsed.start.row,
|
|
1109
|
-
endRow: parsed.end.row,
|
|
1110
|
-
startCol: parsed.start.col,
|
|
1111
|
-
endCol: parsed.end.col,
|
|
1112
|
-
};
|
|
1113
|
-
}
|
|
1114
|
-
case 'call':
|
|
1115
|
-
return instruction.argRefs
|
|
1116
|
-
? {
|
|
1117
|
-
...instruction,
|
|
1118
|
-
argRefs: instruction.argRefs.map((argRef) => argRef ? rewriteReferenceOperand(argRef, ownerSheetName, targetSheetName, transform) : argRef),
|
|
1119
|
-
}
|
|
1120
|
-
: instruction;
|
|
1121
|
-
case 'push-lambda':
|
|
1122
|
-
return {
|
|
1123
|
-
...instruction,
|
|
1124
|
-
body: instruction.body.map((step) => rewriteJsPlanInstruction(step, ownerSheetName, targetSheetName, transform)),
|
|
1125
|
-
};
|
|
1126
|
-
case 'push-number':
|
|
1127
|
-
case 'push-boolean':
|
|
1128
|
-
case 'push-string':
|
|
1129
|
-
case 'push-error':
|
|
1130
|
-
case 'push-name':
|
|
1131
|
-
case 'unary':
|
|
1132
|
-
case 'binary':
|
|
1133
|
-
case 'invoke':
|
|
1134
|
-
case 'begin-scope':
|
|
1135
|
-
case 'bind-name':
|
|
1136
|
-
case 'end-scope':
|
|
1137
|
-
case 'jump-if-false':
|
|
1138
|
-
case 'jump':
|
|
1139
|
-
case 'return':
|
|
1140
|
-
return instruction;
|
|
1141
|
-
}
|
|
1142
|
-
}
|
|
1143
168
|
function translateJsPlanInstruction(instruction, rowDelta, colDelta) {
|
|
1144
169
|
switch (instruction.opcode) {
|
|
1145
170
|
case 'push-cell':
|
|
@@ -1262,27 +287,6 @@ function translateJsPlanInstructionWithoutAst(instruction, translatedCellMap, tr
|
|
|
1262
287
|
return instruction;
|
|
1263
288
|
}
|
|
1264
289
|
}
|
|
1265
|
-
function rewriteReferenceOperand(operand, ownerSheetName, targetSheetName, transform) {
|
|
1266
|
-
switch (operand.kind) {
|
|
1267
|
-
case 'cell':
|
|
1268
|
-
return operand.address
|
|
1269
|
-
? {
|
|
1270
|
-
...operand,
|
|
1271
|
-
address: rewriteReferenceOperandAddress(operand.sheetName, operand.address, ownerSheetName, targetSheetName, transform),
|
|
1272
|
-
}
|
|
1273
|
-
: operand;
|
|
1274
|
-
case 'range': {
|
|
1275
|
-
if (!operand.start || !operand.end || !operand.refKind) {
|
|
1276
|
-
return operand;
|
|
1277
|
-
}
|
|
1278
|
-
const nextRange = rewritePlanRangeInstruction(operand.sheetName, operand.start, operand.end, operand.refKind, ownerSheetName, targetSheetName, transform);
|
|
1279
|
-
return nextRange ? { ...operand, ...nextRange } : operand;
|
|
1280
|
-
}
|
|
1281
|
-
case 'row':
|
|
1282
|
-
case 'col':
|
|
1283
|
-
return operand;
|
|
1284
|
-
}
|
|
1285
|
-
}
|
|
1286
290
|
function translateReferenceOperand(operand, rowDelta, colDelta) {
|
|
1287
291
|
switch (operand.kind) {
|
|
1288
292
|
case 'cell':
|
|
@@ -1349,37 +353,6 @@ function translateReferenceOperandWithoutAst(operand, translatedCellMap, transla
|
|
|
1349
353
|
return translateReferenceOperand(operand, rowDelta, colDelta);
|
|
1350
354
|
}
|
|
1351
355
|
}
|
|
1352
|
-
function rewriteReferenceOperandAddress(explicitSheetName, address, ownerSheetName, targetSheetName, transform) {
|
|
1353
|
-
if ((explicitSheetName ?? ownerSheetName) !== targetSheetName) {
|
|
1354
|
-
return address;
|
|
1355
|
-
}
|
|
1356
|
-
return rewriteAddressForStructuralTransform(address, transform) ?? address;
|
|
1357
|
-
}
|
|
1358
|
-
function rewritePlanRangeInstruction(explicitSheetName, start, end, refKind, ownerSheetName, targetSheetName, transform) {
|
|
1359
|
-
if ((explicitSheetName ?? ownerSheetName) !== targetSheetName) {
|
|
1360
|
-
return undefined;
|
|
1361
|
-
}
|
|
1362
|
-
if (refKind === 'cells') {
|
|
1363
|
-
const nextRange = rewriteRangeForStructuralTransform(start, end, transform);
|
|
1364
|
-
return nextRange
|
|
1365
|
-
? {
|
|
1366
|
-
start: nextRange.startAddress,
|
|
1367
|
-
end: nextRange.endAddress,
|
|
1368
|
-
}
|
|
1369
|
-
: undefined;
|
|
1370
|
-
}
|
|
1371
|
-
if ((refKind === 'rows' && transform.axis !== 'row') || (refKind === 'cols' && transform.axis !== 'column')) {
|
|
1372
|
-
return undefined;
|
|
1373
|
-
}
|
|
1374
|
-
const parsed = parseRangeAddress(formatQualifiedRangeReference(explicitSheetName, start, end));
|
|
1375
|
-
const nextRange = rewriteRangeAddressForStructuralTransform(parsed, transform);
|
|
1376
|
-
return nextRange
|
|
1377
|
-
? {
|
|
1378
|
-
start: nextRange.start.text,
|
|
1379
|
-
end: nextRange.end.text,
|
|
1380
|
-
}
|
|
1381
|
-
: undefined;
|
|
1382
|
-
}
|
|
1383
356
|
function translatePlanRangeInstruction(explicitSheetName, start, end, rowDelta, colDelta) {
|
|
1384
357
|
const parsed = parseRangeAddress(formatQualifiedRangeReference(explicitSheetName, start, end));
|
|
1385
358
|
const nextRange = translateRangeAddress(parsed, rowDelta, colDelta);
|
|
@@ -1388,267 +361,8 @@ function translatePlanRangeInstruction(explicitSheetName, start, end, rowDelta,
|
|
|
1388
361
|
end: nextRange.end.text,
|
|
1389
362
|
};
|
|
1390
363
|
}
|
|
1391
|
-
function formatQualifiedCellReference(sheetName, address) {
|
|
1392
|
-
if (!sheetName) {
|
|
1393
|
-
return address;
|
|
1394
|
-
}
|
|
1395
|
-
const parsed = parseCellAddress(address, sheetName);
|
|
1396
|
-
return `${quoteSheetNameIfNeeded(sheetName)}!${parsed.text}`;
|
|
1397
|
-
}
|
|
1398
364
|
function formatQualifiedRangeReference(sheetName, start, end) {
|
|
1399
365
|
const prefix = sheetName ? `${quoteSheetNameIfNeeded(sheetName)}!` : '';
|
|
1400
366
|
return `${prefix}${start}:${end}`;
|
|
1401
367
|
}
|
|
1402
|
-
function translateCellReference(ref, rowDelta, colDelta) {
|
|
1403
|
-
const parsed = parseCellReferenceParts(ref);
|
|
1404
|
-
if (!parsed) {
|
|
1405
|
-
throw new Error(`Invalid cell reference '${ref}'`);
|
|
1406
|
-
}
|
|
1407
|
-
const nextCol = parsed.colAbsolute ? parsed.col : parsed.col + colDelta;
|
|
1408
|
-
const nextRow = parsed.rowAbsolute ? parsed.row : parsed.row + rowDelta;
|
|
1409
|
-
if (nextCol < 0 || nextRow < 0) {
|
|
1410
|
-
throw new Error(`Translated reference moved outside worksheet bounds: ${ref}`);
|
|
1411
|
-
}
|
|
1412
|
-
return formatCellReference(parsed, nextRow, nextCol);
|
|
1413
|
-
}
|
|
1414
|
-
function translateColumnReference(ref, colDelta) {
|
|
1415
|
-
const parsed = parseAxisReferenceParts(ref, 'column');
|
|
1416
|
-
if (!parsed) {
|
|
1417
|
-
throw new Error(`Invalid column reference '${ref}'`);
|
|
1418
|
-
}
|
|
1419
|
-
const nextCol = parsed.absolute ? parsed.index : parsed.index + colDelta;
|
|
1420
|
-
if (nextCol < 0) {
|
|
1421
|
-
throw new Error(`Translated reference moved outside worksheet bounds: ${ref}`);
|
|
1422
|
-
}
|
|
1423
|
-
return formatAxisReference(parsed.absolute, nextCol, 'column');
|
|
1424
|
-
}
|
|
1425
|
-
function translateRowReference(ref, rowDelta) {
|
|
1426
|
-
const parsed = parseAxisReferenceParts(ref, 'row');
|
|
1427
|
-
if (!parsed) {
|
|
1428
|
-
throw new Error(`Invalid row reference '${ref}'`);
|
|
1429
|
-
}
|
|
1430
|
-
const nextRow = parsed.absolute ? parsed.index : parsed.index + rowDelta;
|
|
1431
|
-
if (nextRow < 0) {
|
|
1432
|
-
throw new Error(`Translated reference moved outside worksheet bounds: ${ref}`);
|
|
1433
|
-
}
|
|
1434
|
-
return formatAxisReference(parsed.absolute, nextRow, 'row');
|
|
1435
|
-
}
|
|
1436
|
-
export function serializeFormula(node, parentPrecedence = 0, parentAssociativity = null) {
|
|
1437
|
-
switch (node.kind) {
|
|
1438
|
-
case 'NumberLiteral':
|
|
1439
|
-
return String(node.value);
|
|
1440
|
-
case 'BooleanLiteral':
|
|
1441
|
-
return node.value ? 'TRUE' : 'FALSE';
|
|
1442
|
-
case 'StringLiteral':
|
|
1443
|
-
return `"${node.value.replaceAll('"', '""')}"`;
|
|
1444
|
-
case 'ErrorLiteral':
|
|
1445
|
-
return ERROR_LITERAL_TEXT[node.code] ?? '#ERROR!';
|
|
1446
|
-
case 'NameRef':
|
|
1447
|
-
return node.name;
|
|
1448
|
-
case 'StructuredRef':
|
|
1449
|
-
return `${node.tableName}[${node.columnName}]`;
|
|
1450
|
-
case 'CellRef':
|
|
1451
|
-
return `${formatSheetPrefix(node.sheetName)}${node.ref}`;
|
|
1452
|
-
case 'SpillRef':
|
|
1453
|
-
return `${formatSheetPrefix(node.sheetName)}${node.ref}#`;
|
|
1454
|
-
case 'ColumnRef':
|
|
1455
|
-
return `${formatSheetPrefix(node.sheetName)}${node.ref}`;
|
|
1456
|
-
case 'RowRef':
|
|
1457
|
-
return `${formatSheetPrefix(node.sheetName)}${node.ref}`;
|
|
1458
|
-
case 'RangeRef':
|
|
1459
|
-
return `${formatSheetPrefix(node.sheetName)}${node.start}:${node.end}`;
|
|
1460
|
-
case 'UnaryExpr':
|
|
1461
|
-
return `${node.operator}${serializeFormula(node.argument, 6)}`;
|
|
1462
|
-
case 'CallExpr':
|
|
1463
|
-
return `${node.callee}(${node.args.map((arg) => serializeFormula(arg)).join(',')})`;
|
|
1464
|
-
case 'InvokeExpr': {
|
|
1465
|
-
const callee = node.callee.kind === 'CallExpr' || node.callee.kind === 'InvokeExpr'
|
|
1466
|
-
? serializeFormula(node.callee)
|
|
1467
|
-
: `(${serializeFormula(node.callee)})`;
|
|
1468
|
-
return `${callee}(${node.args.map((arg) => serializeFormula(arg)).join(',')})`;
|
|
1469
|
-
}
|
|
1470
|
-
case 'BinaryExpr': {
|
|
1471
|
-
const precedence = BINARY_PRECEDENCE[node.operator];
|
|
1472
|
-
const isRightAssociative = node.operator === '^';
|
|
1473
|
-
const left = serializeFormula(node.left, precedence, 'left');
|
|
1474
|
-
const right = serializeFormula(node.right, precedence, 'right');
|
|
1475
|
-
const output = `${left}${node.operator}${right}`;
|
|
1476
|
-
const needsParens = precedence < parentPrecedence ||
|
|
1477
|
-
(precedence === parentPrecedence &&
|
|
1478
|
-
((parentAssociativity === 'left' && isRightAssociative) || (parentAssociativity === 'right' && !isRightAssociative)));
|
|
1479
|
-
return needsParens ? `(${output})` : output;
|
|
1480
|
-
}
|
|
1481
|
-
}
|
|
1482
|
-
}
|
|
1483
|
-
function formatSheetPrefix(sheetName) {
|
|
1484
|
-
if (!sheetName) {
|
|
1485
|
-
return '';
|
|
1486
|
-
}
|
|
1487
|
-
return `${quoteSheetNameIfNeeded(sheetName)}!`;
|
|
1488
|
-
}
|
|
1489
|
-
function quoteSheetNameIfNeeded(sheetName) {
|
|
1490
|
-
return /^[A-Za-z0-9_.$]+$/.test(sheetName) ? sheetName : `'${sheetName.replaceAll("'", "''")}'`;
|
|
1491
|
-
}
|
|
1492
|
-
function columnToIndex(column) {
|
|
1493
|
-
let value = 0;
|
|
1494
|
-
for (const char of column) {
|
|
1495
|
-
value = value * 26 + (char.charCodeAt(0) - 64);
|
|
1496
|
-
}
|
|
1497
|
-
return value - 1;
|
|
1498
|
-
}
|
|
1499
|
-
function indexToColumn(index) {
|
|
1500
|
-
let current = index + 1;
|
|
1501
|
-
let output = '';
|
|
1502
|
-
while (current > 0) {
|
|
1503
|
-
const remainder = (current - 1) % 26;
|
|
1504
|
-
output = String.fromCharCode(65 + remainder) + output;
|
|
1505
|
-
current = Math.floor((current - 1) / 26);
|
|
1506
|
-
}
|
|
1507
|
-
return output;
|
|
1508
|
-
}
|
|
1509
|
-
function targetsSheet(explicitSheetName, ownerSheetName, targetSheetName) {
|
|
1510
|
-
return (explicitSheetName ?? ownerSheetName) === targetSheetName;
|
|
1511
|
-
}
|
|
1512
|
-
function parseCellReferenceParts(ref) {
|
|
1513
|
-
const match = CELL_REF_RE.exec(ref.toUpperCase());
|
|
1514
|
-
if (!match) {
|
|
1515
|
-
return undefined;
|
|
1516
|
-
}
|
|
1517
|
-
const [, colAbsolute, columnText, rowAbsolute, rowText] = match;
|
|
1518
|
-
return {
|
|
1519
|
-
colAbsolute: colAbsolute === '$',
|
|
1520
|
-
rowAbsolute: rowAbsolute === '$',
|
|
1521
|
-
col: columnToIndex(columnText),
|
|
1522
|
-
row: Number.parseInt(rowText, 10) - 1,
|
|
1523
|
-
};
|
|
1524
|
-
}
|
|
1525
|
-
function formatCellReference(parts, row, col) {
|
|
1526
|
-
return `${parts.colAbsolute ? '$' : ''}${indexToColumn(col)}${parts.rowAbsolute ? '$' : ''}${row + 1}`;
|
|
1527
|
-
}
|
|
1528
|
-
function parseAxisReferenceParts(ref, kind) {
|
|
1529
|
-
const match = (kind === 'row' ? ROW_REF_RE : COLUMN_REF_RE).exec(ref.toUpperCase());
|
|
1530
|
-
if (!match) {
|
|
1531
|
-
return undefined;
|
|
1532
|
-
}
|
|
1533
|
-
return kind === 'row'
|
|
1534
|
-
? {
|
|
1535
|
-
absolute: match[1] === '$',
|
|
1536
|
-
index: Number.parseInt(match[2], 10) - 1,
|
|
1537
|
-
}
|
|
1538
|
-
: {
|
|
1539
|
-
absolute: match[1] === '$',
|
|
1540
|
-
index: columnToIndex(match[2]),
|
|
1541
|
-
};
|
|
1542
|
-
}
|
|
1543
|
-
function formatAxisReference(absolute, index, kind) {
|
|
1544
|
-
const prefix = absolute ? '$' : '';
|
|
1545
|
-
return kind === 'row' ? `${prefix}${index + 1}` : `${prefix}${indexToColumn(index)}`;
|
|
1546
|
-
}
|
|
1547
|
-
function mapPointIndex(index, transform) {
|
|
1548
|
-
switch (transform.kind) {
|
|
1549
|
-
case 'insert':
|
|
1550
|
-
return index >= transform.start ? index + transform.count : index;
|
|
1551
|
-
case 'delete':
|
|
1552
|
-
if (index < transform.start) {
|
|
1553
|
-
return index;
|
|
1554
|
-
}
|
|
1555
|
-
if (index >= transform.start + transform.count) {
|
|
1556
|
-
return index - transform.count;
|
|
1557
|
-
}
|
|
1558
|
-
return undefined;
|
|
1559
|
-
case 'move':
|
|
1560
|
-
if (transform.target < transform.start) {
|
|
1561
|
-
if (index >= transform.target && index < transform.start) {
|
|
1562
|
-
return index + transform.count;
|
|
1563
|
-
}
|
|
1564
|
-
}
|
|
1565
|
-
else if (transform.target > transform.start) {
|
|
1566
|
-
if (index >= transform.start + transform.count && index < transform.target + transform.count) {
|
|
1567
|
-
return index - transform.count;
|
|
1568
|
-
}
|
|
1569
|
-
}
|
|
1570
|
-
if (index >= transform.start && index < transform.start + transform.count) {
|
|
1571
|
-
return transform.target + (index - transform.start);
|
|
1572
|
-
}
|
|
1573
|
-
return index;
|
|
1574
|
-
default:
|
|
1575
|
-
return assertNever(transform);
|
|
1576
|
-
}
|
|
1577
|
-
}
|
|
1578
|
-
function mapInterval(start, end, transform) {
|
|
1579
|
-
switch (transform.kind) {
|
|
1580
|
-
case 'insert': {
|
|
1581
|
-
if (transform.start <= start) {
|
|
1582
|
-
return { start: start + transform.count, end: end + transform.count };
|
|
1583
|
-
}
|
|
1584
|
-
if (transform.start <= end) {
|
|
1585
|
-
return { start, end: end + transform.count };
|
|
1586
|
-
}
|
|
1587
|
-
return { start, end };
|
|
1588
|
-
}
|
|
1589
|
-
case 'delete': {
|
|
1590
|
-
const deleteEnd = transform.start + transform.count - 1;
|
|
1591
|
-
if (deleteEnd < start) {
|
|
1592
|
-
return { start: start - transform.count, end: end - transform.count };
|
|
1593
|
-
}
|
|
1594
|
-
if (transform.start > end) {
|
|
1595
|
-
return { start, end };
|
|
1596
|
-
}
|
|
1597
|
-
const survivingStart = start < transform.start ? start : deleteEnd + 1;
|
|
1598
|
-
const survivingEnd = end > deleteEnd ? end : transform.start - 1;
|
|
1599
|
-
if (survivingStart > survivingEnd) {
|
|
1600
|
-
return undefined;
|
|
1601
|
-
}
|
|
1602
|
-
const nextStart = mapPointIndex(survivingStart, transform);
|
|
1603
|
-
const nextEnd = mapPointIndex(survivingEnd, transform);
|
|
1604
|
-
return nextStart === undefined || nextEnd === undefined ? undefined : { start: nextStart, end: nextEnd };
|
|
1605
|
-
}
|
|
1606
|
-
case 'move': {
|
|
1607
|
-
const segments = transform.target < transform.start
|
|
1608
|
-
? [
|
|
1609
|
-
{ start: 0, end: transform.target - 1, delta: 0 },
|
|
1610
|
-
{ start: transform.target, end: transform.start - 1, delta: transform.count },
|
|
1611
|
-
{
|
|
1612
|
-
start: transform.start,
|
|
1613
|
-
end: transform.start + transform.count - 1,
|
|
1614
|
-
delta: transform.target - transform.start,
|
|
1615
|
-
},
|
|
1616
|
-
{ start: transform.start + transform.count, end: Number.MAX_SAFE_INTEGER, delta: 0 },
|
|
1617
|
-
]
|
|
1618
|
-
: [
|
|
1619
|
-
{ start: 0, end: transform.start - 1, delta: 0 },
|
|
1620
|
-
{
|
|
1621
|
-
start: transform.start,
|
|
1622
|
-
end: transform.start + transform.count - 1,
|
|
1623
|
-
delta: transform.target - transform.start,
|
|
1624
|
-
},
|
|
1625
|
-
{
|
|
1626
|
-
start: transform.start + transform.count,
|
|
1627
|
-
end: transform.target + transform.count - 1,
|
|
1628
|
-
delta: -transform.count,
|
|
1629
|
-
},
|
|
1630
|
-
{ start: transform.target + transform.count, end: Number.MAX_SAFE_INTEGER, delta: 0 },
|
|
1631
|
-
];
|
|
1632
|
-
let nextStart;
|
|
1633
|
-
let nextEnd;
|
|
1634
|
-
segments.forEach((segment) => {
|
|
1635
|
-
const overlapStart = Math.max(start, segment.start);
|
|
1636
|
-
const overlapEnd = Math.min(end, segment.end);
|
|
1637
|
-
if (overlapStart > overlapEnd) {
|
|
1638
|
-
return;
|
|
1639
|
-
}
|
|
1640
|
-
const mappedStart = overlapStart + segment.delta;
|
|
1641
|
-
const mappedEnd = overlapEnd + segment.delta;
|
|
1642
|
-
nextStart = nextStart === undefined ? mappedStart : Math.min(nextStart, mappedStart);
|
|
1643
|
-
nextEnd = nextEnd === undefined ? mappedEnd : Math.max(nextEnd, mappedEnd);
|
|
1644
|
-
});
|
|
1645
|
-
if (nextStart === undefined || nextEnd === undefined) {
|
|
1646
|
-
return undefined;
|
|
1647
|
-
}
|
|
1648
|
-
return { start: nextStart, end: nextEnd };
|
|
1649
|
-
}
|
|
1650
|
-
default:
|
|
1651
|
-
return assertNever(transform);
|
|
1652
|
-
}
|
|
1653
|
-
}
|
|
1654
368
|
//# sourceMappingURL=translation.js.map
|