import type { Mapping } from '@volar/source-map'; import type { LinkedCodeMap } from './linkedCodeMap'; export interface Mapper { mappings: Mapping[]; toSourceRange(start: number, end: number, fallbackToAnyMatch: boolean, filter?: (data: CodeInformation) => boolean): Generator, Mapping]>; toGeneratedRange(start: number, end: number, fallbackToAnyMatch: boolean, filter?: (data: CodeInformation) => boolean): Generator, Mapping]>; toSourceLocation(generatedOffset: number, filter?: (data: CodeInformation) => boolean): Generator]>; toGeneratedLocation(sourceOffset: number, filter?: (data: CodeInformation) => boolean): Generator]>; } export type MapperFactory = (mappings: Mapping[]) => Mapper; export interface Language { mapperFactory: MapperFactory; plugins: LanguagePlugin[]; scripts: { get(id: T, includeFsFiles?: boolean): SourceScript | undefined; set(id: T, snapshot: IScriptSnapshot, languageId?: string, plugins?: LanguagePlugin[]): SourceScript | undefined; delete(id: T): void; fromVirtualCode(virtualCode: VirtualCode): SourceScript; }; maps: { get(virtualCode: VirtualCode, sourceScript: SourceScript): Mapper; forEach(virtualCode: VirtualCode): Generator<[sourceScript: SourceScript, map: Mapper]>; }; linkedCodeMaps: { get(virtualCode: VirtualCode): LinkedCodeMap | undefined; }; } export interface SourceScript { id: T; languageId: string; snapshot: IScriptSnapshot; targetIds: Set; associatedIds: Set; associatedOnly: boolean; isAssociationDirty?: boolean; generated?: { root: VirtualCode; languagePlugin: LanguagePlugin; embeddedCodes: Map; }; } export type CodeMapping = Mapping; export interface VirtualCode { id: string; languageId: string; snapshot: IScriptSnapshot; mappings: CodeMapping[]; associatedScriptMappings?: Map; embeddedCodes?: VirtualCode[]; linkedCodeMappings?: Mapping[]; } export interface CodeInformation { /** virtual code is expected to support verification */ verification?: boolean | { shouldReport?(source: string | undefined, code: string | number | undefined): boolean; }; /** virtual code is expected to support assisted completion */ completion?: boolean | { isAdditional?: boolean; onlyImport?: boolean; }; /** virtual code is expected correctly reflect semantic of the source code */ semantic?: boolean | { shouldHighlight?(): boolean; }; /** virtual code is expected correctly reflect reference relationships of the source code */ navigation?: boolean | { shouldRename?(): boolean; resolveRenameNewName?(newName: string): string; resolveRenameEditText?(newText: string): string; }; /** virtual code is expected correctly reflect the structural information of the source code */ structure?: boolean; /** virtual code is expected correctly reflect the format information of the source code */ format?: boolean; } export interface LanguagePlugin { /** * For files that are not opened in the IDE, the language ID will not be synchronized to the language server, so a hook is needed to parse the language ID of files that are known extension but not opened in the IDE. */ getLanguageId(scriptId: T): string | undefined; /** * Generate a virtual code. */ createVirtualCode?(scriptId: T, languageId: string, snapshot: IScriptSnapshot, ctx: CodegenContext): K | undefined; /** * Incremental update a virtual code. If not provide, call createVirtualCode again. */ updateVirtualCode?(scriptId: T, virtualCode: K, newSnapshot: IScriptSnapshot, ctx: CodegenContext): K | undefined; /** * Cleanup a virtual code. */ disposeVirtualCode?(scriptId: T, virtualCode: K): void; /** * Some file types should not be parsed or processed as TypeScript files, * as they are used only as sources for generated files. * * This functionality is required only in TS plugin mode. */ isAssociatedFileOnly?(scriptId: T, languageId: string): boolean; } export interface CodegenContext { getAssociatedScript(scriptId: T): SourceScript | undefined; } export interface IScriptSnapshot { /** Gets a portion of the script snapshot specified by [start, end). */ getText(start: number, end: number): string; /** Gets the length of this script snapshot. */ getLength(): number; /** * Gets the TextChangeRange that describe how the text changed between this text and * an older version. This information is used by the incremental parser to determine * what sections of the script need to be re-parsed. 'undefined' can be returned if the * change range cannot be determined. However, in that case, incremental parsing will * not happen and the entire document will be re - parsed. */ getChangeRange(oldSnapshot: IScriptSnapshot): TextChangeRange | undefined; /** Releases all resources held by this script snapshot */ dispose?(): void; } export interface TextChangeRange { span: TextSpan; newLength: number; } export interface TextSpan { start: number; length: number; }