| 245 | } |
| 246 | // Find a function definition by any means necessary (unless it is ambiguous) |
| 247 | #getFunction(key, values, forceUnique) { |
| 248 | // Selector |
| 249 | if (isHexString(key)) { |
| 250 | const selector = key.toLowerCase(); |
| 251 | for (const fragment of this.#functions.values()) { |
| 252 | if (selector === fragment.selector) { |
| 253 | return fragment; |
| 254 | } |
| 255 | } |
| 256 | return null; |
| 257 | } |
| 258 | // It is a bare name, look up the function (will return null if ambiguous) |
| 259 | if (key.indexOf("(") === -1) { |
| 260 | const matching = []; |
| 261 | for (const [name, fragment] of this.#functions) { |
| 262 | if (name.split("(" /* fix:) */)[0] === key) { |
| 263 | matching.push(fragment); |
| 264 | } |
| 265 | } |
| 266 | if (values) { |
| 267 | const lastValue = (values.length > 0) ? values[values.length - 1] : null; |
| 268 | let valueLength = values.length; |
| 269 | let allowOptions = true; |
| 270 | if (Typed.isTyped(lastValue) && lastValue.type === "overrides") { |
| 271 | allowOptions = false; |
| 272 | valueLength--; |
| 273 | } |
| 274 | // Remove all matches that don't have a compatible length. The args |
| 275 | // may contain an overrides, so the match may have n or n - 1 parameters |
| 276 | for (let i = matching.length - 1; i >= 0; i--) { |
| 277 | const inputs = matching[i].inputs.length; |
| 278 | if (inputs !== valueLength && (!allowOptions || inputs !== valueLength - 1)) { |
| 279 | matching.splice(i, 1); |
| 280 | } |
| 281 | } |
| 282 | // Remove all matches that don't match the Typed signature |
| 283 | for (let i = matching.length - 1; i >= 0; i--) { |
| 284 | const inputs = matching[i].inputs; |
| 285 | for (let j = 0; j < values.length; j++) { |
| 286 | // Not a typed value |
| 287 | if (!Typed.isTyped(values[j])) { |
| 288 | continue; |
| 289 | } |
| 290 | // We are past the inputs |
| 291 | if (j >= inputs.length) { |
| 292 | if (values[j].type === "overrides") { |
| 293 | continue; |
| 294 | } |
| 295 | matching.splice(i, 1); |
| 296 | break; |
| 297 | } |
| 298 | // Make sure the value type matches the input type |
| 299 | if (values[j].type !== inputs[j].baseType) { |
| 300 | matching.splice(i, 1); |
| 301 | break; |
| 302 | } |
| 303 | } |
| 304 | } |