import { Lang } from "@ast-grep/napi";
export interface ImportInfo {
    moduleSpecifier: string;
    isDynamic: boolean;
    /** CommonJS require uses a different conditional-export branch from import. */
    isRequire?: boolean;
    isCssImport?: boolean;
    /**
     * Fallback specifier when the primary moduleSpecifier cannot be resolved.
     * Used by Godot .tscn/.tres ext_resource: when both uid:// and path are
     * present, uid is the primary specifier and path is the fallback, so the
     * resolver can try the path if UID resolution misses.
     */
    fallbackSpecifier?: string;
    /**
     * True when the specifier comes from a declaration that brings a file into
     * the module tree — a Rust `mod foo;` — rather than from a path that merely
     * names something. Rust needs the difference: a module has to be declared
     * before an unanchored path can reach it, and the declaration is the only
     * evidence of that in the file.
     */
    isModuleDeclaration?: boolean;
    /**
     * The name a module declaration puts in the declaring file's own scope.
     * Absent when the declaration is written inside an inline `mod` block,
     * where the name belongs to the block rather than to the file.
     *
     * It is not the specifier: `#[path = "custom.rs"] mod foo;` travels as the
     * path it declares, while the name it brings into scope is `foo`, and it is
     * `foo` an unanchored `use foo::Item;` in that file may reach.
     */
    declaredName?: string;
    /**
     * True when the path was written inside an inline `mod { … }` block and its
     * head is not a module that block declares. Such a head cannot reach a module
     * the *file* declares: rustc asks for an anchor first. Checked on cargo
     * 1.98.0 — `pub mod corelib;` at file level with `use corelib::marker;`
     * inside `pub mod block { … }` is E0432, "a similar path exists: use
     * crate::corelib::marker" (`super::` where the block sits deeper).
     *
     * It is the mirror of the case already handled the other way round, where a
     * declaration written inside a block does not count at file level.
     */
    fromInlineBlock?: boolean;
    /** Distinguishes Godot path semantics for extends, preload, and runtime load. */
    godotImportKind?: "extends" | "preload" | "load";
}
/**
 * Reset the per-language dedupe set. Intended for tests that want to assert
 * deterministically on extraction warnings.
 */
export declare function resetImportExtractionWarnings(): void;
/**
 * Decode a GDScript string literal from its raw source text.
 *
 * GDScript supports:
 *   - Single-quoted: 'hello', '''triple single'''
 *   - Double-quoted: "hello", \"\"\"triple double\"\\"\"
 *   - Raw strings: r"no escapes", r'no escapes', r\"\"\"triple\"\"
 *
 * In raw strings, escape sequences are not processed — the content is
 * taken literally. In non-raw strings, \\n, \\t, \\\\, \\", \\', \\uXXXX
 * are decoded.
 *
 * Returns the decoded string value, or null if the text is not a valid
 * GDScript string literal.
 */
export declare function decodeGdscriptString(raw: string): string | null;
/**
 * Parse a TSCN/.tres section header line into its resource type and
 * key-value attributes.
 *
 * TSCN whitespace is insignificant outside strings. Headings are:
 *   [<resource_type> key1=value1 key2=value2 ...]
 *
 * This tokenizer handles:
 *   - Leading whitespace before [
 *   - Spaces around = in key=value pairs
 *   - Quoted values with escapes
 *   - Arbitrary attribute order
 *   - Comments (lines starting with ; outside a section)
 *
 * Returns { type, attrs } or null if the line is not a section header.
 */
export declare function parseTscnSectionHeader(line: string): {
    type: string;
    attrs: Map<string, string>;
} | null;
/**
 * Syntax-aware GDScript import fallback for hosts where the optional native
 * parser cannot load. The lightweight lexer excludes comments and string
 * bodies before recognizing direct preload/load arguments and extends forms.
 */
export declare function extractGdscriptImportsRegex(source: string): ImportInfo[];
/**
 * Tokenizer-based import extraction for Godot resource files (.tscn/.tres).
 *
 * These are text-based INI-like files with no tree-sitter grammar.
 * Dependencies are declared via `[ext_resource path="..."]` lines.
 *
 * The path can be:
 *   - A `res://` path (absolute within the Godot project)
 *   - A relative path (relative to the .tscn/.tres file's directory)
 *   - A `uid://` path (resolved via .uid sidecar files)
 *
 * TSCN whitespace is insignificant outside strings, so the tokenizer handles
 * leading whitespace, spaces around =, arbitrary attribute order, and quoted
 * values with escapes. See the TSCN documentation:
 * https://docs.godotengine.org/en/stable/engine_details/file_formats/tscn.html
 *
 * Scene-to-scene composition is represented by PackedScene entries in
 * ext_resource, not a separate [instance] section. The `instance` keyword
 * is an attribute of a [node] declaration, not a section heading.
 *
 * Both `uid` and `path` attributes are extracted. When both are present,
 * Godot prefers the UID and falls back to the text path only when the UID
 * cannot be resolved. The resolver handles this priority.
 */
export declare function extractGodotResourceImports(source: string): ImportInfo[];
/** The subset of the ast-grep node API this module reads. */
interface SgNodeLike {
    kind(): string;
    text(): string;
    parent(): SgNodeLike | null;
    prev(): SgNodeLike | null;
    field(name: string): SgNodeLike | null;
    findAll(matcher: {
        rule: {
            kind: string;
        };
    }): SgNodeLike[];
    children(): SgNodeLike[];
    range(): {
        start: {
            index: number;
        };
        end: {
            index: number;
        };
    };
}
/**
 * Flatten one `use` tree into the module paths it names, one per leaf:
 *
 *   crate::config::Config     → ["crate::config::Config"]
 *   crate::{a::Thing, b}      → ["crate::a::Thing", "crate::b"]
 *   crate::a::{self, b as c}  → ["crate::a", "crate::a::b"]
 *   crate::a::*               → ["crate::a"]
 *
 * A braced group is not a module path and never resolved to one; recording the
 * leaves instead is what lets `use crate::{parser, printer}` draw an edge to
 * each of the two files rather than to their parent module — or, in a flat
 * crate with no parent module file, to nothing at all.
 */
export declare function expandRustUseTree(tree: string): string[];
/** A half-open range of character indexes in a source. */
interface Span {
    start: number;
    end: number;
}
interface UnwrappedSource {
    /** The rewritten Rust source. */
    source: string;
    /** Its tree, already built by the check that accepted it. */
    root: SgNodeLike;
    /**
     * Every ERROR node that tree holds — each inside a macro unwrapped in this
     * pass or an earlier one, or the check would not have accepted it. The next
     * pass forgives exactly these, and nothing else.
     */
    errors: Span[];
}
/**
 * Extract import statements from source code using ast-grep.
 * Returns raw module specifiers for each language's import syntax.
 *
 * `unwrapped` is internal, and only the Rust macro pass passes it: the tree it
 * had to build to accept the source it rewrote, so the same text is not parsed
 * twice, and the regions it blanked, which the next pass needs to tell its own
 * damage from the last pass's leftovers. Nothing else should pass it — it
 * describes one particular `source` and would be read as if it described this
 * one.
 */
export declare function extractImports(source: string, lang: Lang | string, ext: string, unwrapPassesLeft?: number, unwrapped?: UnwrappedSource): ImportInfo[];
export {};
//# sourceMappingURL=graph-imports.d.ts.map