Skip to content

Commit 30e4ae4

Browse files
committed
Refactor SheetMapping
1 parent f20718a commit 30e4ae4

File tree

8 files changed

+50
-58
lines changed

8 files changed

+50
-58
lines changed

src/DependencyGraph/DependencyGraph.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -322,7 +322,7 @@ export class DependencyGraph {
322322
this.sheetMapping.removeSheet(sheetBeingRemoved)
323323
this.addressMapping.removeSheet(sheetBeingRemoved)
324324
} else {
325-
this.sheetMapping.softRemoveSheet(sheetBeingRemoved)
325+
this.sheetMapping.markSheetAsPlaceholder(sheetBeingRemoved)
326326
}
327327

328328
this.stats.measure(StatType.ADJUSTING_RANGES, () => {
@@ -624,23 +624,23 @@ export class DependencyGraph {
624624
}
625625

626626
public getCellValue(address: SimpleCellAddress): InterpreterValue {
627-
if (address.sheet !== NamedExpressions.SHEET_FOR_WORKBOOK_EXPRESSIONS && !this.sheetMapping.hasSheetWithId(address.sheet, { includeNotAdded: false })) {
627+
if (address.sheet !== NamedExpressions.SHEET_FOR_WORKBOOK_EXPRESSIONS && !this.sheetMapping.hasSheetWithId(address.sheet, { includePlaceholders: false })) {
628628
return new CellError(ErrorType.REF, ErrorMessage.SheetRef)
629629
}
630630

631631
return this.addressMapping.getCellValue(address)
632632
}
633633

634634
public getRawValue(address: SimpleCellAddress): RawCellContent {
635-
if (address.sheet !== NamedExpressions.SHEET_FOR_WORKBOOK_EXPRESSIONS && !this.sheetMapping.hasSheetWithId(address.sheet, { includeNotAdded: false })) {
635+
if (address.sheet !== NamedExpressions.SHEET_FOR_WORKBOOK_EXPRESSIONS && !this.sheetMapping.hasSheetWithId(address.sheet, { includePlaceholders: false })) {
636636
return null
637637
}
638638

639639
return this.addressMapping.getRawValue(address)
640640
}
641641

642642
public getScalarValue(address: SimpleCellAddress): InternalScalarValue {
643-
if (address.sheet !== NamedExpressions.SHEET_FOR_WORKBOOK_EXPRESSIONS && !this.sheetMapping.hasSheetWithId(address.sheet, { includeNotAdded: false })) {
643+
if (address.sheet !== NamedExpressions.SHEET_FOR_WORKBOOK_EXPRESSIONS && !this.sheetMapping.hasSheetWithId(address.sheet, { includePlaceholders: false })) {
644644
return new CellError(ErrorType.REF, ErrorMessage.SheetRef)
645645
}
646646

@@ -1196,11 +1196,11 @@ export class DependencyGraph {
11961196

11971197
const hasDependentInExistingSheet = dependents.some(addr => {
11981198
if (isSimpleCellAddress(addr)) {
1199-
return addr.sheet === NamedExpressions.SHEET_FOR_WORKBOOK_EXPRESSIONS || this.sheetMapping.hasSheetWithId(addr.sheet, { includeNotAdded: false })
1199+
return addr.sheet === NamedExpressions.SHEET_FOR_WORKBOOK_EXPRESSIONS || this.sheetMapping.hasSheetWithId(addr.sheet, { includePlaceholders: false })
12001200
}
12011201

12021202
if (isSimpleCellRange(addr)) {
1203-
return this.sheetMapping.hasSheetWithId(addr.start.sheet, { includeNotAdded: false }) || this.sheetMapping.hasSheetWithId(addr.end.sheet, { includeNotAdded: false })
1203+
return this.sheetMapping.hasSheetWithId(addr.start.sheet, { includePlaceholders: false }) || this.sheetMapping.hasSheetWithId(addr.end.sheet, { includePlaceholders: false })
12041204
}
12051205

12061206
return false

src/DependencyGraph/SheetMapping.ts

Lines changed: 37 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import {Maybe} from '../Maybe'
1111
* Options for querying the sheet mapping.
1212
*/
1313
export interface SheetMappingQueryOptions {
14-
includeNotAdded?: boolean,
14+
includePlaceholders?: boolean,
1515
}
1616

1717
/**
@@ -21,12 +21,8 @@ class Sheet {
2121
constructor(
2222
public readonly id: number,
2323
public displayName: string,
24-
/**
25-
* Whether the sheet has been explicitly added to the instance either on initialization or via addSheet method.
26-
*/
27-
public isAdded: boolean = true,
28-
) {
29-
}
24+
public isPlaceholder: boolean = false,
25+
) {}
3026

3127
/**
3228
* Returns the canonical (normalized) name of the sheet.
@@ -39,9 +35,9 @@ class Sheet {
3935
/**
4036
* Manages the sheets in the instance.
4137
* Can convert between sheet names and ids and vice versa.
42-
* Also stores placeholders for sheets that are used in formulas but not yet added. They are marked as isAdded=false.
38+
* Also stores placeholders for sheets that are used in formulas but not yet added. They are marked as isPlaceholder=true.
4339
* Sheetnames thet differ only in case are considered the same. (See: canonicalizeSheetName)
44-
*/
40+
*/
4541
export class SheetMapping {
4642
/**
4743
* Prefix for new sheet names if no name is provided by the user
@@ -73,16 +69,14 @@ export class SheetMapping {
7369
}
7470

7571
/**
76-
* Returns sheet ID for the given name (case-insensitive). By default excludes not added sheets.
77-
*
78-
* @returns {Maybe<number>} the sheet ID, or undefined if not found.
72+
* Returns sheet ID for the given name. By default excludes placeholders.
7973
*/
8074
public getSheetId(sheetName: string, options: SheetMappingQueryOptions = {}): Maybe<number> {
8175
return this._getSheetByName(sheetName, options)?.id
8276
}
8377

8478
/**
85-
* Returns sheet ID for the given name. Excludes not added sheets.
79+
* Returns sheet ID for the given name. Excludes placeholders.
8680
*
8781
* @throws {NoSheetWithNameError} if the sheet with the given name does not exist.
8882
*/
@@ -96,7 +90,7 @@ export class SheetMapping {
9690
}
9791

9892
/**
99-
* Returns display name for the given sheet ID. Excludes not added sheets.
93+
* Returns display name for the given sheet ID. Excludes placeholders.
10094
*
10195
* @returns {Maybe<string>} the display name, or undefined if the sheet with the given ID does not exist.
10296
*/
@@ -105,7 +99,7 @@ export class SheetMapping {
10599
}
106100

107101
/**
108-
* Returns display name for the given sheet ID. Excludes not added sheets.
102+
* Returns display name for the given sheet ID. Excludes placeholders.
109103
*
110104
* @throws {NoSheetWithIdError} if the sheet with the given ID does not exist.
111105
*/
@@ -114,60 +108,59 @@ export class SheetMapping {
114108
}
115109

116110
/**
117-
* Iterates over all sheet display names. By default excludes not added sheets.
111+
* Iterates over all sheet display names. By default excludes placeholders.
118112
*/
119113
public* iterateSheetNames(options: SheetMappingQueryOptions = {}): IterableIterator<string> {
120114
for (const sheet of this.allSheets.values()) {
121-
if (options.includeNotAdded || sheet.isAdded) {
115+
if (options.includePlaceholders || !sheet.isPlaceholder) {
122116
yield sheet.displayName
123117
}
124118
}
125119
}
126120

127121
/**
128-
* Returns array of all sheet display names. By default excludes not added sheets.
122+
* Returns array of all sheet display names. By default excludes placeholders.
129123
*/
130124
public getSheetNames(options: SheetMappingQueryOptions = {}): string[] {
131125
return Array.from(this.iterateSheetNames(options))
132126
}
133127

134128
/**
135-
* Returns total count of sheets. By default excludes not added sheets.
129+
* Returns total count of sheets. By default excludes placeholders.
136130
*/
137131
public numberOfSheets(options: SheetMappingQueryOptions = {}): number {
138132
return this.getSheetNames(options).length
139133
}
140134

141135
/**
142-
* Checks if sheet with given ID exists. By default excludes not added sheets.
136+
* Checks if sheet with given ID exists. By default excludes placeholders.
143137
*/
144138
public hasSheetWithId(sheetId: number, options: SheetMappingQueryOptions = {}): boolean {
145139
return this._getSheet(sheetId, options) !== undefined
146140
}
147141

148142
/**
149-
* Checks if sheet with given name exists (case-insensitive). Excludes not added sheets.
143+
* Checks if sheet with given name exists (case-insensitive). Excludes placeholders.
150144
*/
151145
public hasSheetWithName(sheetName: string): boolean {
152146
return this._getSheetByName(sheetName, {}) !== undefined
153147
}
154148

155149
/**
156150
* Adds new sheet with optional name and returns its ID.
157-
* If called with a reserved sheet name (sheet name of some sheet present in the mapping but not added yet), adds the reserved sheet.
151+
* If called with a name of placeholder sheet, adds the real sheet.
158152
*
159153
* @throws {SheetNameAlreadyTakenError} if the sheet with the given name already exists.
160-
* @returns {number} the ID of the new sheet.
161154
*/
162155
public addSheet(newSheetDisplayName: string = `${this.sheetNamePrefix}${this.lastSheetId + 2}`): number {
163-
const sheetWithConflictingName = this._getSheetByName(newSheetDisplayName, { includeNotAdded: true })
156+
const sheetWithConflictingName = this._getSheetByName(newSheetDisplayName, { includePlaceholders: true })
164157

165158
if (sheetWithConflictingName) {
166-
if (sheetWithConflictingName.isAdded) {
159+
if (!sheetWithConflictingName.isPlaceholder) {
167160
throw new SheetNameAlreadyTakenError(newSheetDisplayName)
168161
}
169162

170-
sheetWithConflictingName.isAdded = true
163+
sheetWithConflictingName.isPlaceholder = false
171164
return sheetWithConflictingName.id
172165
}
173166

@@ -178,49 +171,48 @@ export class SheetMapping {
178171
}
179172

180173
/**
181-
* Stores the sheet in the mapping with flag isAdded=false.
182-
* If such sheet name is already present in the mapping, does nothing.
183-
*
184-
* @returns {number} the ID of the reserved sheet.
174+
* Adds a placeholder sheet with the given name if it does not exist yet
185175
*/
186-
public reserveSheetName(sheetName: string): number {
187-
const sheetWithConflictingName = this._getSheetByName(sheetName, { includeNotAdded: true })
176+
public addPlaceholderIfNotExists(sheetName: string): number {
177+
const sheetWithConflictingName = this._getSheetByName(sheetName, { includePlaceholders: true })
188178

189179
if (sheetWithConflictingName) {
190180
return sheetWithConflictingName.id
191181
}
192182

193183
this.lastSheetId++
194-
const sheet = new Sheet(this.lastSheetId, sheetName, false)
184+
const sheet = new Sheet(this.lastSheetId, sheetName, true)
195185
this.storeSheetInMappings(sheet)
196186
return sheet.id
197187
}
198188

199189
/**
200-
* Removes sheet with given ID. Ignores not added sheets.
201-
*
202-
* @throws {NoSheetWithIdError} if the sheet with the given ID does not exist or is not added yet.
190+
* Removes sheet with given ID. Ignores placeholders
191+
* @throws {NoSheetWithIdError} if the sheet with the given ID does not exist or is a placeholder
203192
*/
204193
public removeSheet(sheetId: number): void {
205-
const sheet = this._getSheetOrThrowError(sheetId, {})
194+
const sheet = this._getSheetOrThrowError(sheetId, { includePlaceholders: false })
206195
this.allSheets.delete(sheetId)
207196
this.mappingFromCanonicalNameToId.delete(sheet.canonicalName)
208197
}
209198

210-
public softRemoveSheet(sheetId: number): void {
199+
/**
200+
* Marks sheet with given ID as a placeholder.
201+
* @throws {NoSheetWithIdError} if the sheet with the given ID does not exist
202+
*/
203+
public markSheetAsPlaceholder(sheetId: number): void {
211204
const sheet = this._getSheetOrThrowError(sheetId, {})
212-
sheet.isAdded = false
205+
sheet.isPlaceholder = true
213206
}
214207

215208
/**
216209
* Renames sheet.
217-
* If called with sheetId of a not added sheet, throws {NoSheetWithIdError}.
210+
* If called with sheetId of a placeholder sheet, throws {NoSheetWithIdError}.
218211
* If newDisplayName is conflicting with an existing sheet, throws {SheetNameAlreadyTakenError}.
219-
* If newDisplayName is conflicting with a reserved sheet name (name of a non-added sheet), throws {SheetNameAlreadyTakenError}.
212+
* If newDisplayName is conflicting with a placeholder sheet name, throws {SheetNameAlreadyTakenError}.
220213
*
221214
* @throws {SheetNameAlreadyTakenError} if the sheet with the given name already exists.
222215
* @throws {NoSheetWithIdError} if the sheet with the given ID does not exist.
223-
* @returns {Maybe<string>} the old name, or undefined if the name was not changed.
224216
*/
225217
public renameSheet(sheetId: number, newDisplayName: string): { previousDisplayName: Maybe<string>, mergedSheetWith?: number } {
226218
const sheet = this._getSheetOrThrowError(sheetId, {})
@@ -230,11 +222,11 @@ export class SheetMapping {
230222
return { previousDisplayName: undefined }
231223
}
232224

225+
const sheetWithConflictingName = this._getSheetByName(newDisplayName, { includePlaceholders: true })
233226
let mergedSheetWith: number | undefined = undefined
234-
const sheetWithConflictingName = this._getSheetByName(newDisplayName, { includeNotAdded: true })
235227

236228
if (sheetWithConflictingName !== undefined && sheetWithConflictingName.id !== sheet.id) {
237-
if (sheetWithConflictingName.isAdded) {
229+
if (!sheetWithConflictingName.isPlaceholder) {
238230
throw new SheetNameAlreadyTakenError(newDisplayName)
239231
} else {
240232
this.mappingFromCanonicalNameToId.delete(sheetWithConflictingName.canonicalName)
@@ -277,7 +269,7 @@ export class SheetMapping {
277269
return undefined
278270
}
279271

280-
return (options.includeNotAdded || retrievedSheet.isAdded) ? retrievedSheet : undefined
272+
return (options.includePlaceholders || !retrievedSheet.isPlaceholder) ? retrievedSheet : undefined
281273
}
282274

283275
/**

src/DependencyGraph/SheetReferenceRegistrar.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ export class SheetReferenceRegistrar {
2323
* @returns the sheet identifier that represents the referenced sheet
2424
*/
2525
public ensureSheetRegistered(sheetName: string): number {
26-
const sheetId = this.sheetMapping.reserveSheetName(sheetName)
26+
const sheetId = this.sheetMapping.addPlaceholderIfNotExists(sheetName)
2727
this.addressMapping.addSheetStrategyPlaceholderIfNotExists(sheetId)
2828
return sheetId
2929
}

src/interpreter/Interpreter.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -288,7 +288,7 @@ export class Interpreter {
288288
}
289289

290290
private isSheetJustReserved(address: AddressWithSheet): boolean {
291-
return address.sheet !== undefined && address.sheet !== NamedExpressions.SHEET_FOR_WORKBOOK_EXPRESSIONS && !this.dependencyGraph.sheetMapping.hasSheetWithId(address.sheet, { includeNotAdded: false })
291+
return address.sheet !== undefined && address.sheet !== NamedExpressions.SHEET_FOR_WORKBOOK_EXPRESSIONS && !this.dependencyGraph.sheetMapping.hasSheetWithId(address.sheet, { includePlaceholders: false })
292292
}
293293

294294
private rangeSpansOneSheet(ast: CellRangeAst | ColumnRangeAst | RowRangeAst): boolean {

src/interpreter/plugin/NumericAggregationPlugin.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -629,7 +629,7 @@ export class NumericAggregationPlugin extends FunctionPlugin implements Function
629629
}
630630
}
631631

632-
if (!this.dependencyGraph.sheetMapping.hasSheetWithId(range.start.sheet, { includeNotAdded: false }) || !this.dependencyGraph.sheetMapping.hasSheetWithId(range.end.sheet, { includeNotAdded: false })) {
632+
if (!this.dependencyGraph.sheetMapping.hasSheetWithId(range.start.sheet, { includePlaceholders: false }) || !this.dependencyGraph.sheetMapping.hasSheetWithId(range.end.sheet, { includePlaceholders: false })) {
633633
return new CellError(ErrorType.REF, ErrorMessage.SheetRef)
634634
}
635635

src/parser/Unparser.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ export class Unparser {
109109
}
110110

111111
private unparseSheetName(sheetId: number): string {
112-
const sheetName = sheetIndexToString(sheetId, id => this.sheetMapping.getSheetNameOrThrowError(id, { includeNotAdded: true }))
112+
const sheetName = sheetIndexToString(sheetId, id => this.sheetMapping.getSheetNameOrThrowError(id, { includePlaceholders: true }))
113113
if (sheetName === undefined) {
114114
throw new NoSheetWithIdError(sheetId)
115115
}

test/unit/dependency-graph-sheet-reference-registrar.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ describe('SheetReferenceRegistrar', () => {
1313
const secondSheetId = registrar.ensureSheetRegistered('Ghost')
1414

1515
expect(firstSheetId).toBe(secondSheetId)
16-
expect(sheetMapping.getSheetId('Ghost', {includeNotAdded: true})).toBe(firstSheetId)
16+
expect(sheetMapping.getSheetId('Ghost', {includePlaceholders: true})).toBe(firstSheetId)
1717
expect(() => addressMapping.getStrategyForSheet(firstSheetId)).not.toThrow()
1818
})
1919
})

test/unit/graphComparator.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@ export class EngineComparator {
2121
}
2222

2323
public compare(): void {
24-
const expectedNumberOfSheets = this.expected.sheetMapping.numberOfSheets({includeNotAdded: true})
25-
const numberOfSheets = this.actual.sheetMapping.numberOfSheets({includeNotAdded: true})
24+
const expectedNumberOfSheets = this.expected.sheetMapping.numberOfSheets({includePlaceholders: true})
25+
const numberOfSheets = this.actual.sheetMapping.numberOfSheets({includePlaceholders: true})
2626

2727
if (expectedNumberOfSheets !== numberOfSheets) {
2828
throw Error(`Expected number of sheets ${expectedNumberOfSheets}, actual: ${numberOfSheets}`)

0 commit comments

Comments
 (0)