| 86 | } |
| 87 | |
| 88 | class FunctionNode extends Node { |
| 89 | /** |
| 90 | * @constructor FunctionNode |
| 91 | * @extends {./Node} |
| 92 | * invoke a list with arguments on a node |
| 93 | * @param {./Node | string} fn |
| 94 | * Item resolving to a function on which to invoke |
| 95 | * the arguments, typically a SymbolNode or AccessorNode |
| 96 | * @param {./Node[]} args |
| 97 | */ |
| 98 | constructor (fn, args, optional) { |
| 99 | super() |
| 100 | if (typeof fn === 'string') { |
| 101 | fn = new SymbolNode(fn) |
| 102 | } |
| 103 | |
| 104 | // validate input |
| 105 | if (!isNode(fn)) throw new TypeError('Node expected as parameter "fn"') |
| 106 | if (!Array.isArray(args) || !args.every(isNode)) { |
| 107 | throw new TypeError( |
| 108 | 'Array containing Nodes expected for parameter "args"') |
| 109 | } |
| 110 | const optionalType = typeof optional |
| 111 | if (!(optionalType === 'undefined' || optionalType === 'boolean')) { |
| 112 | throw new TypeError('optional flag, if specified, must be boolean') |
| 113 | } |
| 114 | |
| 115 | this.fn = fn |
| 116 | this.args = args || [] |
| 117 | this.optional = !!optional |
| 118 | } |
| 119 | |
| 120 | // readonly property name |
| 121 | get name () { |
| 122 | return this.fn.name || '' |
| 123 | } |
| 124 | |
| 125 | static name = name |
| 126 | get type () { return name } |
| 127 | get isFunctionNode () { return true } |
| 128 | |
| 129 | /** |
| 130 | * Compile a node into a JavaScript function. |
| 131 | * This basically pre-calculates as much as possible and only leaves open |
| 132 | * calculations which depend on a dynamic scope with variables. |
| 133 | * @param {Object} math Math.js namespace with functions and constants. |
| 134 | * @param {Object} argNames An object with argument names as key and `true` |
| 135 | * as value. Used in the SymbolNode to optimize |
| 136 | * for arguments from user assigned functions |
| 137 | * (see FunctionAssignmentNode) or special symbols |
| 138 | * like `end` (see IndexNode). |
| 139 | * @return {function} Returns a function which can be called like: |
| 140 | * evalNode(scope: Object, args: Object, context: *) |
| 141 | */ |
| 142 | _compile (math, argNames) { |
| 143 | // compile arguments |
| 144 | const evalArgs = this.args.map((arg) => arg._compile(math, argNames)) |
| 145 | const fromOptionalChaining = this.optional || |
nothing calls this directly
no outgoing calls
no test coverage detected
searching dependent graphs…