hyperformula-dc
Version:
HyperFormula is a JavaScript engine for efficient processing of spreadsheet-like data and formulas
205 lines (204 loc) • 7.23 kB
TypeScript
/**
* @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;
}