UNPKG

hyperformula-dc

Version:

HyperFormula is a JavaScript engine for efficient processing of spreadsheet-like data and formulas

205 lines (204 loc) 7.23 kB
/** * @license * Copyright (c) 2021 Handsoncode. All rights reserved. */ import { ArraySize, ArraySizePredictor } from '../../ArraySize'; import { CellError, SimpleCellAddress } from '../../Cell'; import { Config } from '../../Config'; import { DateTimeHelper } from '../../DateTimeHelper'; import { DependencyGraph } from '../../DependencyGraph'; import { SearchStrategy } from '../../Lookup/SearchStrategy'; import { Maybe } from '../../Maybe'; import { Ast, ProcedureAst } from '../../parser'; import { Serialization } from '../../Serialization'; import { ArithmeticHelper, complex } from '../ArithmeticHelper'; import { Interpreter } from '../Interpreter'; import { InterpreterState } from '../InterpreterState'; import { ExtendedNumber, InternalScalarValue, InterpreterValue, NumberType, RawNoErrorScalarValue, RawScalarValue } from '../InterpreterValue'; export interface ImplementedFunctions { [formulaId: string]: FunctionMetadata; } export interface FunctionMetadata { /** * Internal and engine. */ parameters?: FunctionArgument[]; /** * Internal. * * For functions with a variable number of arguments: sets how many last arguments can be repeated indefinitely. */ repeatLastArgs?: number; /** * Internal. * * If set to `true`, ranges in the function's arguments are inlined to (possibly multiple) scalar arguments. */ expandRanges?: boolean; /** * Internal. * * Return number value is packed into this subtype. */ returnNumberType?: NumberType; /** * Engine. */ method: string; /** * Engine. * * If set to `true`, the function is volatile. */ arraySizeMethod?: string; /** * Engine. */ isVolatile?: boolean; /** * Engine. * * If set to `true`, the function gets recalculated with each sheet shape change * (e.g. when adding/removing rows or columns). */ isDependentOnSheetStructureChange?: boolean; /** * Engine. * * If set to `true`, the function treats reference or range arguments as arguments that don't create dependency. * * Other arguments are properly evaluated. */ doesNotNeedArgumentsToBeComputed?: boolean; /** * Engine. * * If set to `true`, the function enables the array arithmetic mode in its arguments and nested expressions. */ arrayFunction?: boolean; /** * Internal. * * If set to `true`, prevents the function from ever being vectorized. * * Some functions do not allow vectorization: array-output, and special functions. */ vectorizationForbidden?: boolean; } export interface FunctionPluginDefinition { new (interpreter: Interpreter): FunctionPlugin; implementedFunctions: ImplementedFunctions; aliases?: { [formulaId: string]: string; }; } export declare enum ArgumentTypes { /** * String type. */ STRING = "STRING", /** * Floating point type. */ NUMBER = "NUMBER", /** * Boolean type. */ BOOLEAN = "BOOLEAN", /** * Any non-range value. */ SCALAR = "SCALAR", /** * Any non-range, no-error type. */ NOERROR = "NOERROR", /** * Range type. */ RANGE = "RANGE", /** * Integer type. */ INTEGER = "INTEGER", /** * String representing complex number. */ COMPLEX = "COMPLEX", /** * Range or scalar. */ ANY = "ANY" } export interface FunctionArgument { argumentType: ArgumentTypes; /** * If set to `true`, arguments need to be passed with full type information. * (e.g. for numbers: `Date` or `DateTime` or `Time` or `Currency` or `Percentage`) */ passSubtype?: boolean; /** * If an argument is missing, its value defaults to `defaultValue`. */ defaultValue?: InternalScalarValue | RawScalarValue; /** * If set to `true`: * if an argument is missing, and no `defaultValue` is set, the argument is `undefined` (instead of throwing an error). * * This is logically equivalent to setting `defaultValue` to `undefined`. */ optionalArg?: boolean; /** * If set, numerical arguments need to be greater than or equal to `minValue`. */ minValue?: number; /** * If set, numerical arguments need to be less than or equal to `maxValue`. */ maxValue?: number; /** * If set, numerical arguments need to be less than `lessThan`. */ lessThan?: number; /** * If set, numerical arguments need to be greater than `greaterThan`. */ greaterThan?: number; } export declare type PluginFunctionType = (ast: ProcedureAst, state: InterpreterState) => InterpreterValue; export declare type PluginArraySizeFunctionType = (ast: ProcedureAst, state: InterpreterState) => ArraySize; export declare type FunctionPluginTypecheck<T> = { [K in keyof T]: T[K] extends PluginFunctionType ? T[K] : T[K] extends PluginArraySizeFunctionType ? T[K] : never; }; /** * Abstract class representing interpreter function plugin. * Plugin may contain multiple functions. Each function should be of type {@link PluginFunctionType} and needs to be * included in {@link implementedFunctions} */ export declare abstract class FunctionPlugin implements FunctionPluginTypecheck<FunctionPlugin> { /** * Dictionary containing functions implemented by specific plugin, along with function name translations. */ static implementedFunctions: ImplementedFunctions; static aliases?: { [formulaId: string]: string; }; protected readonly interpreter: Interpreter; protected readonly dependencyGraph: DependencyGraph; protected readonly columnSearch: SearchStrategy; protected readonly config: Config; protected readonly serialization: Serialization; protected readonly arraySizePredictor: ArraySizePredictor; protected readonly dateTimeHelper: DateTimeHelper; protected readonly arithmeticHelper: ArithmeticHelper; constructor(interpreter: Interpreter); protected evaluateAst(ast: Ast, state: InterpreterState): InterpreterValue; protected arraySizeForAst(ast: Ast, state: InterpreterState): ArraySize; protected listOfScalarValues(asts: Ast[], state: InterpreterState): [InternalScalarValue, boolean][]; protected coerceScalarToNumberOrError: (arg: InternalScalarValue) => ExtendedNumber | CellError; protected coerceToType(arg: InterpreterValue, coercedType: FunctionArgument, state: InterpreterState): Maybe<InterpreterValue | complex | RawNoErrorScalarValue>; protected runFunction: (args: Ast[], state: InterpreterState, metadata: FunctionMetadata, fn: (...arg: any) => InterpreterValue) => InterpreterValue; protected runFunctionWithReferenceArgument: (args: Ast[], state: InterpreterState, metadata: FunctionMetadata, noArgCallback: () => InternalScalarValue, referenceCallback: (reference: SimpleCellAddress) => InternalScalarValue, nonReferenceCallback?: (...arg: any) => InternalScalarValue) => InterpreterValue; protected metadata(name: string): FunctionMetadata; private returnNumberWrapper; }