| 447 | |
| 448 | // Find a function definition by any means necessary (unless it is ambiguous) |
| 449 | #getFunction(key: string, values: null | Array<any | Typed>, forceUnique: boolean): null | FunctionFragment { |
| 450 | |
| 451 | // Selector |
| 452 | if (isHexString(key)) { |
| 453 | const selector = key.toLowerCase(); |
| 454 | for (const fragment of this.#functions.values()) { |
| 455 | if (selector === fragment.selector) { return fragment; } |
| 456 | } |
| 457 | return null; |
| 458 | } |
| 459 | |
| 460 | // It is a bare name, look up the function (will return null if ambiguous) |
| 461 | if (key.indexOf("(") === -1) { |
| 462 | const matching: Array<FunctionFragment> = [ ]; |
| 463 | for (const [ name, fragment ] of this.#functions) { |
| 464 | if (name.split("("/* fix:) */)[0] === key) { matching.push(fragment); } |
| 465 | } |
| 466 | |
| 467 | if (values) { |
| 468 | const lastValue = (values.length > 0) ? values[values.length - 1]: null; |
| 469 | |
| 470 | let valueLength = values.length; |
| 471 | let allowOptions = true; |
| 472 | if (Typed.isTyped(lastValue) && lastValue.type === "overrides") { |
| 473 | allowOptions = false; |
| 474 | valueLength--; |
| 475 | } |
| 476 | |
| 477 | // Remove all matches that don't have a compatible length. The args |
| 478 | // may contain an overrides, so the match may have n or n - 1 parameters |
| 479 | for (let i = matching.length - 1; i >= 0; i--) { |
| 480 | const inputs = matching[i].inputs.length; |
| 481 | if (inputs !== valueLength && (!allowOptions || inputs !== valueLength - 1)) { |
| 482 | matching.splice(i, 1); |
| 483 | } |
| 484 | } |
| 485 | |
| 486 | // Remove all matches that don't match the Typed signature |
| 487 | for (let i = matching.length - 1; i >= 0; i--) { |
| 488 | const inputs = matching[i].inputs; |
| 489 | for (let j = 0; j < values.length; j++) { |
| 490 | // Not a typed value |
| 491 | if (!Typed.isTyped(values[j])) { continue; } |
| 492 | |
| 493 | // We are past the inputs |
| 494 | if (j >= inputs.length) { |
| 495 | if (values[j].type === "overrides") { continue; } |
| 496 | matching.splice(i, 1); |
| 497 | break; |
| 498 | } |
| 499 | |
| 500 | // Make sure the value type matches the input type |
| 501 | if (values[j].type !== inputs[j].baseType) { |
| 502 | matching.splice(i, 1); |
| 503 | break; |
| 504 | } |
| 505 | } |
| 506 | } |