import { Area } from '../../treb-base-types/src/index'; import type { IArea } from '../../treb-base-types/src/index'; import type { ExpressionUnit, Parser } from '../../treb-parser/src/index'; interface NamedExpression { type: 'expression'; expression: ExpressionUnit; } interface NamedRange { type: 'range'; area: Area; } /** @internal */ export type Named = (NamedExpression | NamedRange) & { name: string; scope?: number; }; /** * serialized type is a composite of expression/range. we determine * what it is when parsing the expression. this simplifies passing these * things around. * * (named expressions and ranges they have slightly different behavior, * which is why we have a distinction at all). * */ export interface SerializedNamed { name: string; /** expression or address/area */ expression: string; /** scope is a sheet name (not ID) */ scope?: string; /** * adding type. this is optional, it's not used by tooling. it's * just for informational purpopses for clients. */ type?: 'range' | 'expression'; } /** * this is a replacement for the name manager, which handles * operations relating to named ranges. */ export declare class NamedRangeManager { parser: Parser; /** * this map is stored with normalized names. normalized names * here means we call `toLowerCase`. the objects themselves * contain canonical names. * * ...we've always had a map for this, for fast lookups. but * with scoping, we can't necessarily look up by name. let's try * using scope:name keys. that way we can search for scope:name * and then name and return the first match, if any. * */ protected named: Map; get list(): MapIterator; constructor(parser: Parser); /** shorthand for setting named expression */ SetNamedExpression(name: string, expression: ExpressionUnit, scope?: number): boolean; /** shorthand for setting named range */ SetNamedRange(name: string, area: IArea, scope?: number): boolean; /** * add name. names are case-insensitive. if the name already * exists, it will be overwritten. * * update: returns success (FIXME: proper errors) */ private SetName; private ScopedName; ClearName(name: string, scope?: number): void; /** * if we delete a sheet, remove ranges in that sheet. also remove * anything that's scoped to the sheet. */ RemoveRangesForSheet(sheet_id: number): void; Reset(): void; /** * requiring scope to help propgogate changes. we check the scoped * version first; if that's not found, we default to the global version. * that implies that if there are both, we'll prefer the scoped name. * * now possible to require scope, for qualified scoped names * * Q: why require scope? what's the benefit of that? (...) * */ Get_(name: string, scope: number, require_scope?: boolean): Named | undefined; /** * named range rules: * * - legal characters are alphanumeric, underscore and dot. * * - must start with letter or underscore (not a number or dot). * UPDATE: also possibly a backslash? not sure if that's escaping or not. * * - cannot look like a spreadsheet address, which is 1-3 letters followed by numbers. * UPDATE: actually this is legal if the number is "0". that's the only * number. I don't think our parser will process this correctly, so until * then keep it illegal. * * - apparently questuon marks are legal, but not in first position. atm * our parser will reject. * * - FIXME: we should block R1C1-looking notation as well * * returns a normalized name (just caps, atm) */ ValidateNamed(name: string): string | false; /** * match an area, optionally a target within a larger area (for selections). * we don't use the selection directly, as we may need to adjust target for * merge area. returns the name only if the area is an exact match. */ MatchSelection(area: Area, target?: Area): string | undefined; /** * fix named range references after row/column insert/delete * * surely there's overlap between this function and what we do in * grid when columns are added/removed. can we consolidate? (FIXME/TODO) * */ PatchNamedRanges(sheet_id: number, before_column: number, column_count: number, before_row: number, row_count: number): void; } export {};