import type { PathAliases } from "./graph-aliases.js";
import type { GraphInputRecorder } from "./graph-inputs.js";
/**
 * Whether `seg` names a JVM source-set directory in a `src/<sourceSet>/<lang>`
 * layout. `main` covers the classic Maven/Gradle convention; the `*Main` forms
 * cover Kotlin Multiplatform and Gradle source sets (`commonMain`, `androidMain`,
 * `iosMain`, `jvmMain`, `nativeMain`, `desktopMain`, `appleMain`, `iosArm64Main`, ...).
 */
export declare function isJvmSourceSetDir(seg: string): boolean;
/**
 * Build a suffix lookup map for JVM (Java/Kotlin/Scala) files in multi-module projects.
 *
 * For a Maven/Gradle multi-module layout such as:
 *   module-a/sub-module/src/main/java/com/example/Foo.java
 * the map entry is:
 *   key:   "com/example/Foo.java"  (forward-slash-normalized)
 *   value: "module-a/sub-module/src/main/java/com/example/Foo.java"
 *
 * This enables O(1) resolution of fully-qualified class names that cannot be
 * found via the standard prefix-based scan (e.g. src/main/java/…).
 *
 * Call this once per graph build and pass the result to resolveImport.
 *
 * Classic src/main sources take precedence over KMP source sets. The map view
 * retains the first file within each group; resolveImport can also select a
 * retained KMP candidate matching the importing source set. Pass a
 * lexicographically ordered set (as buildCodeGraph does) for stable picks.
 * Keys are normalized, but values retain the input fileSet paths.
 */
export declare function buildJvmSuffixMap(fileSet: Set<string>): Map<string, string>;
/**
 * Build a namespace lookup map for C# files.
 *
 * Scans every `.cs` file in the project for `namespace X.Y.Z` declarations
 * (both block-scoped `namespace X { ... }` and file-scoped `namespace X;`
 * introduced in C# 10) and builds:
 *
 *   key:   "App.Services"
 *   value: ["src/Services/OrderService.cs", "src/Services/UserService.cs"]
 *
 * Used to resolve `using App.Services;` to the candidate files that
 * contribute to that namespace. Without this, every C# `using` resolved
 * to `null` and C# projects produced an empty file-import graph.
 *
 * Files are processed in lexicographic order so the resulting candidate
 * lists are deterministic across machines and runs. This matters because
 * multi-file namespaces resolve to `candidates[0]` in `resolveImport`,
 * and a stable "first" file is required for reproducible graphs.
 *
 * Cost: O(n) reads at graph-build time (negligible vs. AST parsing). Files
 * with no `namespace` declaration are silently skipped. Read failures are
 * swallowed since this is best-effort.
 */
export declare function buildCsNamespaceMap(fileSet: Set<string>, projectPath: string, recorder?: GraphInputRecorder): Map<string, string[]>;
/**
 * Build a PSR-4 prefix map for PHP projects from every in-repo `composer.json`.
 *
 * PHP namespaces carry no path information — `App\Models\User` only maps to
 * `app/Models/User.php` because `composer.json` says so. The convention-based
 * fallback in `resolveImport` guesses that mapping from the directory layout,
 * which works for a single-package project whose namespace root happens to
 * match a real directory name, and silently drops every import that does not:
 *
 *   - `Database\Seeders\Foo`  → the directory is `database/seeders`, lowercase,
 *                               so the case-sensitive guess misses it
 *   - `Acme\Auth\Models\Role` → lives in `packages/auth/src/Models/Role.php`,
 *                               a path no namespace-shaped guess can reach
 *
 * The second case is the norm in Composer monorepos (path repositories), where
 * every domain package declares its own PSR-4 root. Those imports resolved to
 * nothing, so package-to-package edges were absent from the graph entirely and
 * impact analysis reported "no callers" for code with many callers.
 *
 * Reads the root manifest plus each nested one (`autoload` and `autoload-dev`),
 * mapping every prefix to directories relative to the manifest that declared
 * it.
 *
 * Call this once per graph build and pass the result to resolveImport.
 */
export declare function buildPhpPsr4Map(projectPath: string, recorder?: GraphInputRecorder): Map<string, string[]>;
/**
 * Build a fully-qualified-class-name lookup map for PHP files, derived from
 * the declarations themselves rather than from any manifest.
 *
 * PSR-4 stays the authority wherever it exists, and this map is consulted only
 * after it misses. It exists for the code PSR-4 cannot describe: a package that
 * ships no autoload map at all and registers its namespaces at run time —
 *
 *   $loader->addNamespace('Acme', PLUGIN_DIR . '/src/acme');
 *
 * — which is how WordPress plugins overwhelmingly do it, and which a
 * composer.json reader cannot see. Such a package declares `"autoload": {}` or
 * no manifest at all, so every `use` it makes and every `use` of it resolved to
 * nothing, leaving whole trees orphaned in the graph while their symbols
 * extracted perfectly (issue #120). Interpreting `spl_autoload_register` is not
 * needed to fix that: the file that declares `Acme\Schema\Role` is a fact the
 * source states outright.
 *
 *   key:   "Acme\\Schema\\Role"
 *   value: ["src/acme/schema/RoleSchema.php"]
 *
 * Scans every PHP file unconditionally rather than only those under roots no
 * PSR-4 prefix covers, following `buildCsNamespaceMap`. One map means one
 * resolution regime everywhere, and it keeps working where a composer.json
 * exists but is incomplete — a partial map is the common case, not an edge one.
 *
 * The key is the exact FQCN, declared namespace and declared name together,
 * with no tail matching, so a collision means two files literally declaring the
 * same class — in practice a vendored duplicate. Files are read in
 * lexicographic order and `resolveImport` takes `candidates[0]`, so the pick is
 * deterministic across machines; an edge to either copy is a true "depends on
 * this FQCN" edge, which is why this guesses rather than refusing, matching the
 * C# resolver.
 *
 * Reads `fileSet`, which is already ignore-filtered, so a `vendor/` tree the
 * project excluded contributes nothing and one it deliberately re-included is a
 * legitimate target — no unconditional skip is needed here, unlike the
 * manifest walk in `findComposerManifests`.
 *
 * Declarations are matched by regex at line start, as in `buildCsNamespaceMap`,
 * which costs one read per file instead of a parse. Positional association
 * carries the braced multi-namespace form (`namespace A { … } namespace B { … }`)
 * as well as the file-scoped one. A `class` line inside a heredoc would be
 * matched as a declaration; a false FQCN nobody imports resolves nothing.
 */
export declare function buildPhpFqcnMap(fileSet: Set<string>, projectPath: string, recorder?: GraphInputRecorder): Map<string, string[]>;
/**
 * Information needed to resolve Go imports to local files for ONE module.
 *
 * A project may contain several Go modules (a monorepo with nested
 * `go.mod` files), so {@link buildGoModuleInfo} returns one of these per
 * `go.mod` it discovers. `modulePath` is the value of the `module`
 * directive in `go.mod` (e.g. `github.com/user/repo`); imports starting
 * with this prefix are local to that module. `moduleDir` is the
 * project-relative directory that contains `go.mod` ("." when it sits at
 * the indexed root). `packageMap` maps a Go package's directory *relative
 * to the module directory* (with "." for the module's own root package)
 * to the lex-smallest non-test `.go` file in that directory (stored
 * project-relative), used as a representative target for file-level edges.
 *
 * {@link buildGoModuleInfo} returns an empty array when no `go.mod` is
 * found or none parse. Callers must treat an empty result as "no Go
 * resolution available" and return null for all Go imports.
 */
export interface GoModuleInfo {
    modulePath: string;
    moduleDir: string;
    packageMap: Map<string, string>;
}
/** Map each in-project Elixir `defmodule` name to its files, deterministically. */
export declare function buildElixirModuleMap(fileSet: Set<string>, projectPath: string, recorder?: GraphInputRecorder): Map<string, string[]>;
/**
 * Build Go module-resolution info for a project, one entry per `go.mod`.
 *
 * Discovers EVERY `go.mod` under the project root (so a monorepo with
 * nested modules is supported, not just a single root-level `go.mod`),
 * parses each module path with a regex, and constructs a per-module
 * directory-to-representative-file map across the `.go` files owned by
 * that module. `_test.go` files are excluded — Go does not allow them to
 * be imported from non-test code in other packages. Files are sorted
 * lexicographically before each map is built so the representative
 * chosen for a multi-file package is deterministic across machines/runs.
 *
 * `go.mod` is discovered by walking the tree independently of `fileSet`:
 * `go.mod` has no AST grammar and is not an extra extension, so it is
 * NEVER admitted by `getGraphableFiles` and therefore never present in
 * `fileSet`. An earlier attempt scanned `fileSet` for `go.mod` entries,
 * which matched nothing in a real build and silently broke Go resolution
 * for every project (issue #82, including the root-level #45 case). The
 * walk reuses the same ignore filter `getGraphableFiles` uses, so a
 * `go.mod` inside `node_modules/`, `.git/`, or a gitignored path is
 * skipped.
 *
 * Each `.go` file is attributed to its DEEPEST owning module (the module
 * whose `moduleDir` is the longest directory prefix of the file). The
 * tie-break is directory DEPTH, not string length: the root module
 * (`"."`, depth 0) must never win over a single-segment nested module
 * whose directory name happens to be short (e.g. `z`, which is string
 * length 1 just like `"."`).
 *
 * `packageMap` keys are MODULE-relative (the package directory with the
 * module directory stripped), because a Go import strips the module path
 * down to a module-relative directory. The map VALUES stay
 * project-relative (they are the `fileSet` entries), so resolution needs
 * no further translation even for a nested module.
 *
 * Cost: one tree walk (ignore-filtered) + one `readFileSync` per module
 * plus an O(n) walk over `.go` files at graph-build time. Lookups during
 * resolution are O(1).
 *
 * Limitations (deferred to follow-up issues if reported):
 *   - Parenthesized `module ( ... )` form (rare; not used by any
 *     mainstream Go project).
 *   - `vendor/` directory shadowing of external imports.
 *   - `replace` directives in `go.mod`.
 *   - `go.work` multi-module workspaces.
 */
export declare function buildGoModuleInfo(fileSet: Set<string>, projectPath: string, recorder?: GraphInputRecorder): GoModuleInfo[];
/**
 * Map every in-repo Dart package name to its package root directory
 * (project-relative, forward-slash; `"."` for a root-level `pubspec.yaml`).
 *
 * Dart/Flutter code imports intra-project files by package URI almost
 * exclusively — `import 'package:my_app/src/service.dart';` is the layout
 * convention pub itself generates — and a package URI carries no path
 * information: `package:<name>/<rest>` maps to `<package_root>/lib/<rest>`
 * only because `<name>`'s pubspec lives at `<package_root>`. Without this
 * map every such import resolved to null (issue #106), so Flutter projects
 * lost nearly all file-graph edges and impact analysis reported "no callers"
 * for files with many consumers. Nested manifests are read too, which is what
 * resolves cross-package `package:<sibling>/...` imports in pub-workspace and
 * melos monorepos.
 *
 * The `name:` field is matched only at column 0: pubspec is YAML, so a
 * nested `name:` key legitimately appears indented inside dependency blocks
 * (`dependencies: { foo: { hosted: { name: ... } } }`), and an unanchored
 * match could map a dependency's name to the wrong root. Pub package names
 * are lowercase identifiers (`[a-z0-9_]`); the optional quote accepts the
 * YAML-quoted spelling of the same name. A manifest without a matching
 * `name:` contributes nothing; the first manifest (in sorted path order) to
 * declare a name wins, mirroring `buildJvmSuffixMap`'s first-wins
 * determinism.
 *
 * Call this once per graph build and pass the result to resolveImport.
 */
export declare function buildDartPackageMap(projectPath: string, recorder?: GraphInputRecorder): Map<string, string>;
/**
 * One `pyproject.toml` found in the tree: where it sits, the import roots it
 * implies, and the sibling packages it declares importable.
 */
export interface PythonManifest {
    /** Project-relative directory holding the manifest; `"."` at the root. */
    dir: string;
    /** Import roots it implies: its own directory and its `src/`. */
    roots: string[];
    /**
     * Project-relative directories of the workspace members it declares,
     * resolved against the manifests actually discovered. Empty for a manifest
     * with no `[tool.uv.workspace]` section.
     */
    members: string[];
}
/**
 * Discover every `pyproject.toml` in the tree and record, for each, the import
 * roots it implies and the workspace members it declares.
 *
 * A packaged Python project puts its importable modules under the manifest's
 * directory in one of two layouts: `src/` (what `uv init --lib`, hatchling
 * and setuptools all generate) or flat, directly beside the manifest. Neither
 * is derivable from the import itself. `from usa_wa_adapter_sos.house import
 * build` names no directory that appears in
 * `packages/usa-wa-adapter-sos/src/usa_wa_adapter_sos/house/build.py`: the
 * distribution directory is dashed, the module is underscored, and `src/`
 * sits between them. The resolver's existing project-root `src/`+`lib/` probe
 * only reaches a single-package repo, so in a workspace every cross-package
 * import — and every package's own absolute self-import — resolved to null
 * (issue #107). A 362-file uv workspace built 3 edges.
 *
 * Both roots are recorded per manifest without probing the filesystem for
 * which layout is in use: a root that does not exist holds no files, so it
 * matches nothing, and the check would cost a `stat` per manifest to remove
 * lookups that already miss.
 *
 * Roots are recorded rather than module names enumerated under them. Names
 * would have to come from the directories actually present — a distribution
 * name and its import name are not reliably related (Pillow imports as `PIL`),
 * so `[project] name` cannot supply them — and enumerating directories alone
 * would miss single-module distributions, where `src/mymodule.py` is the whole
 * importable surface and no directory bears the module's name. Trying each
 * root in turn covers both, and covers PEP 420 namespace packages (no
 * `__init__.py`) for free, since it never asks what a directory contains.
 *
 * The only part of a manifest that is read is its `[tool.uv.workspace]`
 * member list, which {@link pythonRootsForFile} needs to tell a sibling
 * package apart from an unrelated project that merely carries a manifest.
 *
 * Sorted by directory so that when two manifests contribute a root holding the
 * same top-level module name, the same one wins on every machine.
 *
 * Call this once per graph build and pass each file's scoped roots (see
 * {@link pythonRootsForFile}) to resolveImport.
 */
export declare function buildPythonManifests(projectPath: string, recorder?: GraphInputRecorder): PythonManifest[];
/**
 * The import roots that apply to one source file, nearest first.
 *
 * Two rules, each fixing a way a flat list of every root in the tree resolves
 * an import to the wrong file:
 *
 * **Scope.** A manifest applies to a file only when it sits on the file's
 * ancestor path, or when an ancestor manifest declares it as a workspace
 * member. A repo's `examples/demo/pyproject.toml`, a checked-in `third_party/`
 * sdist and an editable checkout inside an environment directory all carry
 * manifests while sitting on no `sys.path` the file could import through;
 * without this rule each one registers roots globally and turns an import that
 * correctly resolved to nothing into a fabricated edge. Workspace members are
 * the exception because that is exactly what a member declaration states: the
 * sibling package IS importable from here, and resolving cross-package imports
 * is what issue #107 is about.
 *
 * **Order.** Roots containing the file come first, deepest first, so a package
 * resolves its own modules before a sibling's. Without this, a per-service
 * monorepo of flat `uv init --app` services — each with its own `config.py` —
 * resolved `import config` to whichever service sorted first alphabetically,
 * drawing a confident edge into another service's file. Remaining in-scope
 * roots follow lexicographically: they are the cross-package candidates, where
 * nothing about the import says which package was meant, so the tie is broken
 * the same way on every machine rather than left to walk order.
 *
 * `relSourceDir` is the file's directory, project-relative and
 * forward-slashed, `"."` for a file at the root.
 */
export declare function pythonRootsForFile(manifests: PythonManifest[], relSourceDir: string): string[];
/** One crate found in the tree: what it is called, and where its modules start. */
export interface RustCrate {
    /** Project-relative directory holding its `Cargo.toml`; `"."` at the root. */
    dir: string;
    /**
     * The name other crates import it by — `[package] name` with dashes turned
     * into underscores, which is the translation Cargo itself performs. Null for
     * a manifest that declares no package (a `[workspace]`-only root) or no
     * library target, neither of which anything can import by name.
     */
    name: string | null;
    /**
     * `[package] name` with dashes turned into underscores, which is the name a
     * dependency on this crate is declared under — while `name` above is what
     * the code writes, and the two differ wherever `[lib] name` is set. Null for
     * a manifest that declares no package.
     */
    packageName: string | null;
    /**
     * Set when the manifest could not be parsed. The crate still contributes its
     * convention targets, but nothing is known about what it declares, and a
     * check that reads "declares nothing" off an unread manifest would cost the
     * package every cross-crate edge — one unreadable `Cargo.toml` must not.
     */
    manifestUnread?: true;
    /** Project-relative path of the library root module, when the crate has one. */
    libRoot: string | null;
    /**
     * Project-relative paths of every root module the manifest implies: the
     * library, plus each binary, integration test, example and benchmark, plus
     * the build script. Each is the top of its own module tree, which is what
     * `crate::` is relative to.
     */
    roots: string[];
    /**
     * The Rust edition the manifest declares, defaulting to `"2015"` when the
     * key is absent, as Cargo does. It decides both target autodiscovery and
     * where an unanchored path in a `use` starts counting from.
     */
    edition: string;
    /**
     * Map from local dependency name / alias (with dashes turned to underscores)
     * to the target crate's package name (with dashes turned to underscores).
     *
     * Covers:
     *   [dependencies]
     *   my_alias = { package = "actual-package-name", ... }
     * as well as `[workspace.dependencies]` referenced via `workspace = true`.
     */
    aliases?: Record<string, string>;
    /**
     * The dependency names this manifest fetches from outside the project — a
     * registry or a git remote — rather than from a directory of its own.
     *
     * A dependency with no `path` is a different crate from a project crate that
     * happens to carry the same name, and cargo compiles against the fetched one.
     * `log = "0.4"` beside a workspace member also called `log` drew an edge into
     * that member: verified on cargo 1.98.0 with a `compile_error!` in the local
     * crate, which builds clean because rustc never reads it.
     */
    externalDeps?: string[];
}
/**
 * Build the crate map for a Rust project, one entry per `Cargo.toml`.
 *
 * Rust names its own code three ways, and only one of them says anything about
 * the filesystem. `mod foo;` names a sibling file, which the resolver already
 * followed. `crate::`, `super::` and `self::` name a position in the module
 * tree, whose root is a target's root module — `src/lib.rs`, `src/main.rs`, or
 * whatever `[[bin]] path` declares. `some_crate::` names a whole other crate,
 * which is only in this project if a manifest here declares it, under a name
 * whose dashes Cargo turns into underscores (`sailor-core` is imported as
 * `sailor_core`). None of the three resolved before this map existed: every
 * specifier containing `::` returned null, so a Rust project's file graph came
 * out as its bare `mod` declarations and nothing else.
 *
 * Targets are read from the manifest where declared and taken by convention
 * otherwise, matching Cargo's own autodiscovery rules per edition:
 *   - `autobins`, `autotests`, `autoexamples`, `autobenches`, `autolib` flags
 *     turn off autodiscovery for their respective directories when set to `false`.
 *   - In edition 2015, autodiscovery is turned off by default for a target type
 *     when at least one target of that type is manually declared. In edition
 *     2018+, autodiscovery remains enabled unless explicitly set to `false`.
 *   - `[package] build = false` disables the build script target (`build.rs`).
 *   - `[workspace] exclude` patterns exclude matching directories from being
 *     registered as importable workspace members (`name = null`).
 *
 * The manifest is parsed with the same TOML reader the Python side uses rather
 * than scanned, so a `path` key belonging to a dependency is a different key
 * rather than nearby text. A manifest that cannot be parsed contributes its
 * convention targets and no name: one unreadable `Cargo.toml` must not cost the
 * whole project its Rust edges.
 *
 * Call this once per graph build and pass the result to resolveImport.
 */
export declare function buildRustCrateMap(fileSet: Set<string>, projectPath: string, recorder?: GraphInputRecorder): RustCrate[];
/**
 * Resolve one Rust module path to the project file it names.
 *
 * `relSourceFile` is the importing file, project-relative and forward-slashed.
 * `crates` comes from {@link buildRustCrateMap}; an empty list leaves
 * `crate::` and cross-crate paths unresolved, which is what a tree carrying no
 * `Cargo.toml` should produce.
 *
 * `super::` and `self::` are answered from the file's own position rather than
 * from its crate root, so they resolve in a manifest-less tree too. Climbing
 * stops at the crate root's directory when a root is known: a path cannot leave
 * its crate through `super`, and without the guard `super::super::x` at the top
 * of a workspace member would reach into a sibling's files.
 */
export declare function resolveRustImport(specifier: string, relSourceFile: string, fileSet: Set<string>, crates: RustCrate[], declaredMods?: Map<string, string>, isDeclaration?: boolean): string | null;
/**
 * Pre-built index mapping GDScript class_name declarations to their file paths.
 * Normal graph construction builds one scoped index per Godot project with
 * buildGodotProjectIndexes() to avoid repeated file reads and cross-project
 * name leakage.
 */
export type ClassNameIndex = Map<string, string>;
/**
 * Scan all .gd files in a fileSet for `class_name X` declarations and build
 * a global Map<className, relativePath>.
 *
 * @deprecated Legacy helper retained for compatibility. New graph-building
 * code should use buildGodotProjectIndexes() so class names remain scoped to
 * their nearest Godot project.
 */
export declare function buildClassNameIndex(projectPath: string, fileSet: Set<string>): ClassNameIndex;
/**
 * A per-Godot-project class_name index. Maps each Godot project root
 * (absolute path to the directory containing project.godot) to a
 * ClassNameIndex scoped to the .gd files under that root.
 *
 * This supports repositories with multiple Godot projects (nested or
 * sibling), where each project has its own class_name registry and
 * res:// root. A class_name in one project must not resolve extends
 * in another project.
 */
export type GodotProjectIndexes = Map<string, ClassNameIndex>;
/**
 * A per-Godot-project UID index. Maps `uid://...` strings to relative
 * file paths within the project. Built from `.uid` sidecar files and
 * `uid="uid://..."` attributes in `.tscn`/`.tres` file headers.
 *
 * Godot prefers UIDs over text paths for resource loading. When both
 * are present in an `[ext_resource]` declaration, the UID takes priority
 * and the text path is used only as a fallback when the UID cannot be
 * resolved.
 */
export type GodotUidIndex = Map<string, string>;
export type GodotProjectUidIndexes = Map<string, GodotUidIndex>;
/** Per-graph-build cache for nearest project.godot lookups. */
export type GodotRootCache = Map<string, string | null>;
/**
 * Build per-Godot-project UID indexes from `.uid` sidecar files and
 * `.tscn`/`.tres` file headers.
 *
 * For each `.uid` sidecar file (e.g. `Player.gd.uid`), reads the UID
 * string and maps it to the corresponding resource file. For `.tscn`
 * and `.tres` files, parses the `uid="uid://..."` attribute from the
 * file header.
 *
 * @param projectPath - Absolute path to the SocratiCode indexing root
 * @param fileSet - Set of relative file paths
 * @returns Map of Godot project root (absolute) → UID index (uid:// → relative path)
 */
export declare function buildGodotUidIndexes(projectPath: string, fileSet: Set<string>, rootCache?: GodotRootCache, recorder?: GraphInputRecorder): GodotProjectUidIndexes;
/**
 * Build per-Godot-project class_name indexes for a set of files.
 *
 * For each .gd file, finds the nearest project.godot ancestor and adds
 * the file's class_name to that project's index. Files not under any
 * project.godot are skipped (they have no Godot project context).
 *
 * @param projectPath - Absolute path to the SocratiCode indexing root
 * @param fileSet - Set of relative file paths
 * @returns Map of Godot project root (absolute) → ClassNameIndex (relative paths)
 */
export declare function buildGodotProjectIndexes(projectPath: string, fileSet: Set<string>, rootCache?: GodotRootCache, recorder?: GraphInputRecorder): GodotProjectIndexes;
/**
 * Find the nearest Godot project root for a given source file.
 *
 * Walks up from the file's directory looking for project.godot.
 * Returns the absolute path to the directory containing it, or null
 * if no project.godot is found. This is per-file (not per-repo) to
 * support repositories with multiple Godot projects.
 *
 * @param sourceFile - Absolute path to the source file
 * @param godotProjectIndexes - Retained for compatibility with existing callers.
 * @param rootCache - Optional cache scoped to one graph build.
 */
export declare function findGodotRootForFile(sourceFile: string, _godotProjectIndexes?: GodotProjectIndexes, rootCache?: GodotRootCache): string | null;
/**
 * Resolve a module specifier to a relative file path within the project.
 * Returns null if the module is external (e.g., npm package, stdlib).
 *
 * `language` is a display label as produced by `getLanguageFromExtension`
 * (e.g. "shell", "typescript") — that is what `buildCodeGraph` passes. "bash"
 * has its own case below as a synonym for "shell". The capitalised `Lang`
 * grammar names ("JavaScript", "TypeScript", "Tsx", "Html", "Css") match no
 * case. Not every display label has one either, so a switch miss is always
 * possible, and it returns the same null an external module does.
 *
 * @param aliases - Optional path aliases (tsconfig/jsconfig paths) for JS/TS resolution
 * @param classNameIndex - Pre-built GDScript class_name → file path index for O(1) extends resolution
 * @param godotProjectRoot - Pre-resolved Godot project root (directory containing project.godot).
 *   When provided, res:// paths resolve relative to this instead of walking the filesystem per call.
 * @param godotUidIndex - Pre-built UID → relative path index for uid:// resolution.
 *   When provided, uid:// paths are resolved via this index. When absent,
 *   uid:// paths cannot be resolved and return null.
 * @param fallbackSpecifier - Optional path fallback for a primary uid:// specifier.
 * @param godotImportKind - GDScript construct that supplied the path. Runtime
 *   load paths use the Godot project root; extends and preload use the source directory.
 */
export declare function resolveImport(moduleSpecifier: string, sourceFile: string, projectPath: string, fileSet: Set<string>, language: string, aliases?: PathAliases, jvmSuffixMap?: Map<string, string>, csNamespaceMap?: Map<string, string[]>, goModuleInfo?: GoModuleInfo[] | null, phpPsr4Map?: Map<string, string[]>, dartPackageMap?: Map<string, string>, pythonImportRoots?: string[], elixirModuleMap?: Map<string, string[]>, phpFqcnMap?: Map<string, string[]>, rustCrates?: RustCrate[], rustDeclaredMods?: Map<string, string>, rustIsDeclaration?: boolean, classNameIndex?: ClassNameIndex, godotProjectRoot?: string | null, godotUidIndex?: GodotUidIndex, fallbackSpecifier?: string, godotImportKind?: "extends" | "preload" | "load"): string | null;
/**
 * Whether a shell `source` specifier has the shape of a literal path. This reads
 * the text only — a well-shaped specifier naming a file that does not exist is
 * still true here, and fails later at the file-set lookup.
 *
 * None of the shapes below can be told apart from a literal path here, and each
 * has to be screened before resolution rather than after, because normalising
 * them lands on a file the shell would not open — and a match there is the
 * failure being prevented rather than a salvage:
 *
 * - extractImports captures the whole argument list, so any whitespace-class
 *   character means the text cannot be told apart from a word list or a path
 *   still carrying its quotes. Bash splits on fewer of them than `\s` matches —
 *   its default IFS is space, tab and newline — but skipping all of them errs
 *   toward dropping an edge rather than inventing one.
 * - A backslash is a shell escape and never a separator, so the unescaped path
 *   is unknowable here; `path.resolve` treats it as a separator on win32, which
 *   would cancel `./x\..\lib.sh` down to a file the script never names.
 * - A trailing `/` or `/.` names a directory, which cannot be sourced, and
 *   normalisation would drop that trailing segment, landing on the same-named
 *   file.
 * - A `..` following a named segment cancels it lexically during normalisation,
 *   so `./x/../lib.sh` lands on lib.sh beside the script. The shell walks
 *   components instead and loads nothing when `x` is absent or is not a
 *   directory. Only a leading run of `.`/`..` anchors, and an empty segment from
 *   `//` does not end that run.
 *
 * These screen the raw captured text, so a change that honours quoting and
 * strips arguments has to unquote and split upstream of here.
 */
export declare function hasLiteralShellPathShape(specifier: string): boolean;
/**
 * Find the Godot project root for a set of files by checking if project.godot
 * exists at the project path or any parent. Called once per graph build so
 * that res:// resolution doesn't walk the filesystem for every import.
 * Returns the absolute path to the directory containing project.godot,
 * or null if not found.
 */
export declare function findGodotProjectRootForProject(projectPath: string): string | null;
/**
 * Parse the `[autoload]` section from a Godot `project.godot` file and build
 * a map of autoload name → relative script path.
 *
 * The `[autoload]` section has the form:
 *   [autoload]
 *   GameManager="*res://scripts/core/GameManager.gd"
 *   InputManager="res://scripts/core/InputManager.gd"
 *
 * The leading `*` means the autoload is enabled (singleton). Both `*` and
 * non-`*` entries are included — the autoload name is still a global type
 * regardless of singleton status.
 *
 * @param godotProjectRoot - Absolute path to the directory containing project.godot
 * @returns Map of autoload name → relative path (forward-slash, relative to project root)
 */
export declare function parseGodotAutoloads(godotProjectRoot: string, recorder?: GraphInputRecorder): Map<string, string>;
//# sourceMappingURL=graph-resolution.d.ts.map