/* auto-generated by NAPI-RS */
/* eslint-disable */

import type { Program } from "@oxc-project/types";
import type { VisitorObject } from "./generated/visit/visitor.d.ts";

export * from "@oxc-project/types";

export { VisitorObject };

export const visitorKeys: Record<string, string[]>;

export class Visitor {
  constructor(visitor: VisitorObject);
  visit(program: Program): void;
}
export interface Comment {
  type: 'Line' | 'Block'
  value: string
  start: number
  end: number
}

export interface ErrorLabel {
  message: string | null
  start: number
  end: number
}

export interface OxcError {
  severity: Severity
  message: string
  labels: Array<ErrorLabel>
  helpMessage: string | null
  codeframe: string | null
}

export declare const enum Severity {
  Error = 'Error',
  Warning = 'Warning',
  Advice = 'Advice'
}
export declare class ParseResult {
  get program(): import("@oxc-project/types").Program
  get module(): EcmaScriptModule
  get comments(): Array<Comment>
  get errors(): Array<OxcError>
}

export interface DynamicImport {
  start: number
  end: number
  moduleRequest: Span
}

export interface EcmaScriptModule {
  /**
   * Has ESM syntax.
   *
   * i.e. `import` and `export` statements, and `import.meta`.
   *
   * Dynamic imports `import('foo')` are ignored since they can be used in non-ESM files.
   */
  hasModuleSyntax: boolean
  /** Import statements. */
  staticImports: Array<StaticImport>
  /** Export statements. */
  staticExports: Array<StaticExport>
  /** Dynamic import expressions. */
  dynamicImports: Array<DynamicImport>
  /** Span positions` of `import.meta` */
  importMetas: Array<Span>
}

export interface ExportExportName {
  kind: ExportExportNameKind
  name: string | null
  start: number | null
  end: number | null
}

export declare const enum ExportExportNameKind {
  /** `export { name } */
  Name = 'Name',
  /** `export default expression` */
  Default = 'Default',
  /** `export * from "mod" */
  None = 'None'
}

export interface ExportImportName {
  kind: ExportImportNameKind
  name: string | null
  start: number | null
  end: number | null
}

export declare const enum ExportImportNameKind {
  /** `export { name } */
  Name = 'Name',
  /** `export * as ns from "mod"` */
  All = 'All',
  /** `export * from "mod"` */
  AllButDefault = 'AllButDefault',
  /** Does not have a specifier. */
  None = 'None'
}

export interface ExportLocalName {
  kind: ExportLocalNameKind
  name: string | null
  start: number | null
  end: number | null
}

export declare const enum ExportLocalNameKind {
  /** `export { name } */
  Name = 'Name',
  /** `export default expression` */
  Default = 'Default',
  /**
   * If the exported value is not locally accessible from within the module.
   * `export default function () {}`
   */
  None = 'None'
}

export interface ImportName {
  kind: ImportNameKind
  name: string | null
  start: number | null
  end: number | null
}

export declare const enum ImportNameKind {
  /** `import { x } from "mod"` */
  Name = 'Name',
  /** `import * as ns from "mod"` */
  NamespaceObject = 'NamespaceObject',
  /** `import defaultExport from "mod"` */
  Default = 'Default'
}

/**
 * Parse JS/TS source asynchronously on a separate thread.
 *
 * Note that not all of the workload can happen on a separate thread.
 * Parsing on Rust side does happen in a separate thread, but deserialization of the AST to JS objects
 * has to happen on current thread. This synchronous deserialization work typically outweighs
 * the asynchronous parsing by a factor of between 3 and 20.
 *
 * i.e. the majority of the workload cannot be parallelized by using this method.
 *
 * Generally `parseSync` is preferable to use as it does not have the overhead of spawning a thread.
 * If you need to parallelize parsing multiple files, it is recommended to use worker threads.
 */
export declare function parse(filename: string, sourceText: string, options?: ParserOptions | undefined | null): Promise<ParseResult>

export interface ParserOptions {
  /** Treat the source text as `js`, `jsx`, `ts`, `tsx` or `dts`. */
  lang?: 'js' | 'jsx' | 'ts' | 'tsx' | 'dts'
  /** Treat the source text as `script` or `module` code. */
  sourceType?: 'script' | 'module' | 'commonjs' | 'unambiguous' | undefined
  /**
   * Return an AST which includes TypeScript-related properties, or excludes them.
   *
   * `'js'` is default for JS / JSX files.
   * `'ts'` is default for TS / TSX files.
   * The type of the file is determined from `lang` option, or extension of provided `filename`.
   */
  astType?: 'js' | 'ts'
  /**
   * Controls whether the `range` property is included on AST nodes.
   * The `range` property is a `[number, number]` which indicates the start/end offsets
   * of the node in the file contents.
   *
   * @default false
   */
  range?: boolean
  /**
   * Emit `ParenthesizedExpression` and `TSParenthesizedType` in AST.
   *
   * If this option is true, parenthesized expressions are represented by
   * (non-standard) `ParenthesizedExpression` and `TSParenthesizedType` nodes that
   * have a single `expression` property containing the expression inside parentheses.
   *
   * @default true
   */
  preserveParens?: boolean
  /**
   * Produce semantic errors with an additional AST pass.
   * Semantic errors depend on symbols and scopes, where the parser does not construct.
   * This adds a small performance overhead.
   *
   * @default false
   */
  showSemanticErrors?: boolean
}

/**
 * Parse JS/TS source synchronously on current thread.
 *
 * This is generally preferable over `parse` (async) as it does not have the overhead
 * of spawning a thread, and the majority of the workload cannot be parallelized anyway
 * (see `parse` documentation for details).
 *
 * If you need to parallelize parsing multiple files, it is recommended to use worker threads
 * with `parseSync` rather than using `parse`.
 */
export declare function parseSync(filename: string, sourceText: string, options?: ParserOptions | undefined | null): ParseResult

/** Returns `true` if raw transfer is supported on this platform. */
export declare function rawTransferSupported(): boolean

export interface Span {
  start: number
  end: number
}

export interface StaticExport {
  start: number
  end: number
  entries: Array<StaticExportEntry>
}

export interface StaticExportEntry {
  start: number
  end: number
  moduleRequest: ValueSpan | null
  /** The name under which the desired binding is exported by the module`. */
  importName: ExportImportName
  /** The name used to export this binding by this module. */
  exportName: ExportExportName
  /** The name that is used to locally access the exported value from within the importing module. */
  localName: ExportLocalName
  /**
   * Whether the export is a TypeScript `export type`.
   *
   * Examples:
   *
   * ```ts
   * export type * from 'mod';
   * export type * as ns from 'mod';
   * export type { foo };
   * export { type foo }:
   * export type { foo } from 'mod';
   * ```
   */
  isType: boolean
}

export interface StaticImport {
  /** Start of import statement. */
  start: number
  /** End of import statement. */
  end: number
  /**
   * Import source.
   *
   * ```js
   * import { foo } from "mod";
   * //                   ^^^
   * ```
   */
  moduleRequest: ValueSpan
  /**
   * Import specifiers.
   *
   * Empty for `import "mod"`.
   */
  entries: Array<StaticImportEntry>
}

export interface StaticImportEntry {
  /**
   * The name under which the desired binding is exported by the module.
   *
   * ```js
   * import { foo } from "mod";
   * //       ^^^
   * import { foo as bar } from "mod";
   * //       ^^^
   * ```
   */
  importName: ImportName
  /**
   * The name that is used to locally access the imported value from within the importing module.
   * ```js
   * import { foo } from "mod";
   * //       ^^^
   * import { foo as bar } from "mod";
   * //              ^^^
   * ```
   */
  localName: ValueSpan
  /**
   * Whether this binding is for a TypeScript type-only import.
   *
   * `true` for the following imports:
   * ```ts
   * import type { foo } from "mod";
   * import { type foo } from "mod";
   * ```
   */
  isType: boolean
}

export interface ValueSpan {
  value: string
  start: number
  end: number
}
