UNPKG

@qrvey/formula-lang

Version:

QFormula support for qrvey projects

109 lines 5.21 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.createPositionASTFromSyntaxNode = exports.transformFunctionExpression = void 0; const utils_1 = require("../utils"); const syntax_errors_1 = require("./syntax-errors"); const primitiveFunctions_1 = require("../utils/primitiveFunctions"); const constants_1 = require("../constants"); const functions_1 = require("../functions"); const errors_1 = require("../errors"); const isAggregate_1 = require("../utils/isAggregate"); function transformFunctionExpression(program, node, inference, context, transformNodeFunction) { const fnIdentifier = node.getChild('FunctionIdentifier'); const fnName = (0, utils_1.getNodeValue)(program, fnIdentifier); const fnString = (0, utils_1.getNodeValue)(program, node); const parenthesisStart = node.getChild('ParenthesisStart'); const parenthesisEnd = node.getChild('ParenthesisEnd'); const functionExists = functions_1.FUNCTION_LIST.includes(fnName); const functionDetail = functionExists ? (0, functions_1.getFunctionDetail)(fnName) : undefined; const isAggregated = functionDetail ? functionDetail.operationScope === constants_1.OPERATION_SCOPE.AGGREGATE : false; const args = getFunctionArguments(node, parenthesisStart, program, inference, context, transformNodeFunction); const functionIdentifier = createPositionASTFromSyntaxNode(fnIdentifier); const baseNode = { type: constants_1.AST_TYPES.functionCall, name: (0, utils_1.getNodeValue)(program, fnIdentifier), arguments: args, from: node.from, to: node.to, isValidAggregate: isValidAggFunction(isAggregated, context, args), parenthesisStart: !!parenthesisStart, parenthesisEnd: !!parenthesisEnd, functionText: fnString, functionIdentifier, }; const primitive = functionDetail ? (0, primitiveFunctions_1.getFunctionPrimitive)(functionDetail, baseNode.arguments) : constants_1.AST_PRIMITIVES.UNKNOWN; const resultNode = Object.assign(Object.assign({}, baseNode), { primitive, functionScope: isAggregated ? constants_1.OPERATION_SCOPE.AGGREGATE : constants_1.OPERATION_SCOPE.RAW }); if (functionExists && (!parenthesisStart || !parenthesisEnd)) { inference.errorList.push(new errors_1.MissingParenthesisError(Object.assign(Object.assign({}, resultNode), { from: !parenthesisStart ? resultNode.from : resultNode.to }))); } inference.formulaFunctions.push(resultNode); return resultNode; } exports.transformFunctionExpression = transformFunctionExpression; function getFunctionArguments(fnNode, parenthesisStart, program, inference, context, transformNodeFunction) { const allocatedArgs = []; const args = fnNode.getChild('FunctionArguments'); if (parenthesisStart) { allocatedArgs.push(...getFunctionStartingCommas(fnNode, program, parenthesisStart)); } allocatedArgs.push(...extractFunctionArguments(args, fnNode, program, inference, context, transformNodeFunction)); return allocatedArgs; } function extractFunctionArguments(args, fnNode, program, inference, context, transformNodeFunction) { const resultArgs = []; args === null || args === void 0 ? void 0 : args.cursor().iterate(({ node: argNode }) => { if (argNode.name === 'Expression' || argNode.type.isError) { if (argNode.from === fnNode.to) return false; const astNode = createCommonASTFromNode(program, argNode, inference, context, transformNodeFunction); if (astNode) resultArgs.push(astNode); return false; } }); return resultArgs; } function getFunctionStartingCommas(fnNode, program, parenthesisStart) { const resultArgs = []; fnNode === null || fnNode === void 0 ? void 0 : fnNode.cursor().iterate(({ node: fnNodeChild }) => { if (fnNodeChild.name === 'FunctionArguments') { return false; // Stop entering on function arguments } if (fnNodeChild.type.isError && (0, utils_1.getNodeValue)(program, fnNodeChild) === ',' && fnNodeChild.from > parenthesisStart.from) { const errorNodeStart = parenthesisStart.from + 1; resultArgs.push((0, syntax_errors_1.createUnknownValue)({ from: errorNodeStart, to: fnNodeChild.from, })); } }); return resultArgs; } function createCommonASTFromNode(program, node, inference, context, transformNodeFunction) { if (node.type.isError) { return (0, syntax_errors_1.createUnknownValue)(node); } return transformNodeFunction(program, node, inference, context); } function createPositionASTFromSyntaxNode({ from, to, }) { return { from, to }; } exports.createPositionASTFromSyntaxNode = createPositionASTFromSyntaxNode; function isValidAggFunction(isAggregated, context, args) { if (!(0, isAggregate_1.isAggregateScope)(context)) return true; if (isAggregated) return true; return args.every((arg) => arg.isValidAggregate); } //# sourceMappingURL=formula-parser.js.map