(rhs: string, site: LuaSite, context: ResolutionContext, depth: number)
| 1605 | const luaMembers = (chain: string): string[] => chain.split('.').map((s) => s.trim()).filter(Boolean); |
| 1606 | |
| 1607 | function luaAliasExpr(rhs: string, site: LuaSite, context: ResolutionContext, depth: number): Node | null | undefined { |
| 1608 | const req = LUA_REQUIRE_ALIAS.exec(rhs); |
| 1609 | if (req) return luaModuleMember(req[2]!, luaMembers(req[3]!), site.node, context, depth); |
| 1610 | const named = LUA_NAME_ALIAS.exec(rhs); |
| 1611 | if (!named) return undefined; |
| 1612 | const root = named[1]!; |
| 1613 | const path = luaMembers(named[2]!); |
| 1614 | const rootDecl = root === site.name ? null : luaLocalDecl(root, site.file, site.line - 1, context); |
| 1615 | if (rootDecl) { |
| 1616 | const module = LUA_REQUIRE_ALIAS.exec(rootDecl.signature!.replace(/^\s*=\s*/, '').trim()); |
| 1617 | if (module && path.length > 0) return luaModuleMember(module[2]!, [...luaMembers(module[3]!), ...path], rootDecl, context, depth); |
| 1618 | return undefined; |
| 1619 | } |
| 1620 | if (path.length === 0) return LUA_GLOBAL_FUNCTIONS.has(root) ? null : undefined; |
| 1621 | if (!LUA_LIBRARY_TABLES.has(root)) { |
| 1622 | // A member of a global table the host provides — kong's `local clear_header = |
| 1623 | // kong.response.clear_header` — is the one method of a table named after its holder. |
| 1624 | const member = path[path.length - 1]!; |
| 1625 | const holder = path.length > 1 ? path[path.length - 2]! : root; |
| 1626 | const owned = context.getNodesByName(member).filter((n) => |
| 1627 | (n.language === 'lua' || n.language === 'luau') && n.kind === 'method' && sharesReceiverWord(holder, n) && |
| 1628 | !(isTestPath(n.filePath) && !isTestPath(site.file))); |
| 1629 | return owned.length === 1 ? owned[0]! : undefined; |
| 1630 | } |
| 1631 | if (path.length !== 1) return undefined; |
| 1632 | // A library function the project patches itself (kong's `ngx.sleep`) is the project's — |
| 1633 | // a test's stand-in (`function ngx.get_phase()` in a spec) only for that test. |
| 1634 | const patched = context.getNodesByName(path[0]!).filter((n) => |
| 1635 | (n.kind === 'function' || n.kind === 'method') && n.qualifiedName.split(/::|\./)[0] === root && |
| 1636 | (n.filePath === site.file || !isTestPath(n.filePath))); |
| 1637 | return patched.length === 1 ? patched[0]! : null; |
| 1638 | } |
| 1639 | |
| 1640 | /** Per-context memo: `file\0a.b` → what that module member is. */ |
| 1641 | const LUA_MEMBERS = new WeakMap<ResolutionContext, Map<string, Node | null | undefined>>(); |
no test coverage detected