qingkuai-language-service
Version:
The language service for qingkuai
429 lines (416 loc) • 17.7 kB
TypeScript
import TS from 'typescript';
import * as vscode_languageserver_types from 'vscode-languageserver-types';
import { Range as Range$1, SignatureHelp, CompletionItem } from 'vscode-languageserver-types';
import Prettier, { Options } from 'prettier';
import { Range, Position, Location } from 'vscode-languageserver/node';
import { TextDocument } from 'vscode-languageserver-textdocument';
import { CompileIntermediateResult, ASTLocation, ASTPositionWithFlag, PositionFlag } from 'qingkuai/compiler';
import { HoverSettings } from 'vscode-css-languageservice';
import { CompletionTriggerKind } from 'vscode-languageserver';
type GeneralFunc = (...args: any[]) => any;
type FixedArray<T, L extends number, R extends T[] = []> = R["length"] extends L ? R : FixedArray<T, L, [...R, T]>;
interface createLoggerParams {
write: (msg: string) => void;
prefix?: string;
}
interface CompressedPositions {
flags: Pair<number>[];
lineCharacters: number[];
}
interface TPICCommonRequestParams {
fileName: string;
pos: number;
}
interface GetCompletionsParms {
fileName: string;
pos: number;
triggerCharacter: string;
triggerKind: number | undefined;
}
interface HoverTipResult {
content: string;
range: Pair<number>;
}
interface RenameLocationItem {
fileName: string;
prefix?: string;
suffix?: string;
loc?: Range;
range?: Pair<number>;
}
interface UpdateContentParams {
isTS: boolean;
content: string;
fileName: string;
itos: Pair<number>[];
stoi: Pair<number>[];
positionFlags: Pair<number>[];
getTypeDelayIndexes: number[];
positions: CompressedPositions;
identifierStatusInfo: Record<string, string>;
}
interface UpdateContentResult {
aitos: Pair<number>[];
astoi: Pair<number>[];
}
interface GetClientLanguageConfigResult {
dirPath: string;
prettierConfig: PrettierConfiguration;
qingkuaiConfig: QingkuaiConfiguration;
typescriptConfig: TSClientConfiguration;
extensionConfig: ExtensionConfiguration;
}
interface ResolveCompletionParams {
pos: number;
entryName: string;
fileName: string;
source?: string;
original?: TS.CompletionEntryData;
}
interface FindReferenceResultItem {
fileName: string;
range: Range;
}
interface FindDefinitionsResultItem {
fileName: string;
targetRange: Range;
targetSelectionRange: Range;
}
interface FindDefinitionsResult {
range: Range;
definitions: FindDefinitionsResultItem[];
}
interface InsertSnippetParams {
text: string;
command?: string;
}
interface TSDiagnosticRelatedInformation {
range: Range;
message: string;
filePath: string;
}
interface GetDiagnosticResultItem {
url?: string;
kind: number;
code: number;
range: Range;
source: string;
message: string;
deprecated: boolean;
unnecessary: boolean;
relatedInformations: TSDiagnosticRelatedInformation[];
}
type SignatureHelpParams = TPICCommonRequestParams & {
isRetrigger: boolean;
triggerCharacter?: "," | "(" | "<";
};
type GetCompletionsResultEntry = TS.CompletionEntry & {
label: string;
isColor: boolean;
isDeprecated: boolean;
detail: string | undefined;
};
type GetCompletionsResult = Omit<TS.CompletionInfo, "entries"> & {
entries: GetCompletionsResultEntry[];
};
type Pair<T = any> = FixedArray<T, 2>;
type MaybePromise<T = any> = T | Promise<T>;
type TsNormalizedPath = TS.server.NormalizedPath;
interface GetVscodeRangeFunc {
(loc: ASTLocation): Range$1;
(start: number, end?: number): Range$1;
}
type PromiseWithState<T = any> = Promise<T> & {
state: "fullfilled" | "pending";
};
interface AdapterFS {
read: (path: string) => string;
exist: (path: string) => boolean;
}
interface AdapterPath {
ext: (path: string) => string;
dir: (path: string) => string;
base: (path: string) => string;
resolve: (...segments: string[]) => string;
relative: (from: string, to: string) => string;
}
interface ComponentAttributeItem {
kind: "Props" | "Refs";
name: string;
type: string;
optional: boolean;
mayBeEvent: boolean;
couldBeString: boolean;
stringCandidates: string[];
}
interface ComponentInfo {
name: string;
type: string;
imported: boolean;
slotNames: string[];
relativePath: string;
absolutePath: string;
attributes: ComponentAttributeItem[];
}
interface ExtensionConfiguration {
hoverTipReactiveStatus: boolean;
typescriptDiagnosticsExplain: boolean;
insertSpaceAroundInterpolation: boolean;
additionalCodeLens: ("component" | "slot")[];
componentTagFormatPreference: "camel" | "kebab";
htmlHoverTip: ("tag" | "entity" | "attribute")[];
componentAttributeFormatPreference: "camel" | "kebab";
}
type QingkuaiConfiguration = {
interpretiveComments: boolean;
resolveImportExtension: boolean;
shorthandDerivedDeclaration: boolean;
reactivityMode: "reactive" | "shallow";
whitespace: "preserve" | "trim" | "collapse" | "trim-collapse";
preserveHtmlComments: "all" | "never" | "development" | "production";
};
interface TSClientConfiguration {
preference: TSUserPreferences;
formatCodeSettings: TSFormatCodeSettings;
}
type PrettierConfiguration = Options & {
qingkuai: Partial<{
spaceAroundInterpolation: boolean;
componentTagFormatPreference: "camel" | "kebab";
componentAttributeFormatPreference: "camel" | "kebab";
}>;
};
type CompileResult = CompileIntermediateResult & {
uri: string;
version: number;
filePath: string;
document: TextDocument;
isSynchronized: boolean;
getVscodeRange: GetVscodeRangeFunc;
scriptLanguageId: "typescript" | "javascript";
config: GetClientLanguageConfigResult | null;
};
type TsPluginQingkuaiConfig = Pick<QingkuaiConfiguration, "resolveImportExtension"> & Pick<ExtensionConfiguration, "hoverTipReactiveStatus">;
type TSUserPreferences = TS.server.protocol.UserPreferences;
type TSFormatCodeSettings = TS.server.protocol.FormatCodeSettings;
declare class Logger {
private params;
private prefix;
private target;
constructor(params: createLoggerParams);
private get time();
write(msg: string): void;
info(msg: string, wrapLine?: boolean): void;
warn(msg: string, wrapLine?: boolean): void;
error(msg: string, wrapLine?: boolean): void;
}
declare function createLogger(params: createLoggerParams): Logger;
type LSDiagnostic = TS.Diagnostic & {
url?: string;
};
interface AdapterTsProjectService {
readonly serverMode: TS.LanguageServiceMode;
openFiles: Map<TS.Path, TsNormalizedPath | undefined>;
toPath(fileName: string): TS.Path;
getDefaultProjectForFile(fileName: TsNormalizedPath, ensureProject: boolean): AdapterTsProject | undefined;
forEachProject?(callback: (project: TS.server.Project) => void): void;
}
interface AdapterTsProject {
getScriptFileNames(): string[];
getLanguageService(ensureSynchronized?: boolean): TS.LanguageService;
getScriptKind?: TS.LanguageServiceHost["getScriptKind"];
getScriptVersion?: TS.LanguageServiceHost["getScriptVersion"];
getScriptSnapshot?: TS.LanguageServiceHost["getScriptSnapshot"];
resolveModuleNameLiterals?: TS.LanguageServiceHost["resolveModuleNameLiterals"];
}
declare class LocationConvertor {
private sourceFile;
private adapter;
private filePath;
constructor(adapter: TypescriptAdapter, fileName: string);
lineAndCharacter: {
fromInterIndex: (interIndex: number) => TS.LineAndCharacter;
toInterIndex: (lineAndCharacter: TS.LineAndCharacter) => number;
toSourceLineAndCharacter: (lineAndCharacter: TS.LineAndCharacter) => TS.LineAndCharacter | undefined;
defaultValue: {
line: number;
character: number;
};
};
textSpan: {
toSourceTextSpan: (span: TS.TextSpan) => TS.TextSpan;
defaultValue: {
start: number;
length: number;
};
};
languageServerRange: {
fromTextSpan: (span: TS.TextSpan) => Range$1;
fromSourceTextSpan: (span: TS.TextSpan) => Range$1;
fromSourceStartAndEnd: (sourceStart: number, sourceEnd: number) => Range$1;
defaultValue: {
start: {
line: number;
character: number;
};
end: {
line: number;
character: number;
};
};
};
}
declare class TypescriptAdapter {
ts: typeof TS;
logger: Logger;
fs: AdapterFS;
path: AdapterPath;
compile: CompileIntermidiateFunc;
projectService: AdapterTsProjectService;
getQingkuaiConfig: GetQingkuaiConfigFunc;
updateContent: UpdateQingkuaiFileContentFunc;
getUserPreferences: GetUserPreferencesFunc;
getFormattingOptions: GetFormattingOptionsFunc;
private initialized;
service: AdapterService;
qingkuaiFileInfos: Map<TS.server.NormalizedPath, QingkuaiFileInfo>;
resolvedQingkuaiModules: Map<TS.server.NormalizedPath, Set<string>>;
constructor(ts: typeof TS, logger: Logger, fs: AdapterFS, path: AdapterPath, compile: CompileIntermidiateFunc, projectService: AdapterTsProjectService, getQingkuaiConfig: GetQingkuaiConfigFunc, updateContent: UpdateQingkuaiFileContentFunc, getUserPreferences: GetUserPreferencesFunc, getFormattingOptions: GetFormattingOptionsFunc);
initilize(): void;
markProjectsAsDirty(): void;
forEachProject(callback: (project: TS.server.Project) => void): void;
proxyProject(project: AdapterTsProject): void;
getNormalizedPath(fileName: string): TS.server.NormalizedPath;
getDefaultSourceFile(path: TsNormalizedPath): TS.SourceFile | undefined;
getDefaultProgram(path: TsNormalizedPath): TS.Program | undefined;
getDefaultLanguageService(path: TsNormalizedPath): TS.LanguageService | undefined;
getDefaultProject(path: TsNormalizedPath): AdapterTsProject | undefined;
}
declare class AdapterService {
private adapter;
constructor(adapter: TypescriptAdapter);
getFileReferences(fileName: string, options?: {
recursive?: boolean;
justOpening?: boolean;
}): string[];
isFileOpening(fileName: string): boolean;
createLocationConvertor(fileName: string): LocationConvertor;
getHoverTip(params: TPICCommonRequestParams): HoverTipResult | null;
getDiagnostics(fileName: string): GetDiagnosticResultItem[];
getNavigationTree(fileName: string): TS.NavigationTree | null;
getSignatureHelp(params: SignatureHelpParams): vscode_languageserver_types.SignatureHelp | null;
getImplementations(params: TPICCommonRequestParams): FindReferenceResultItem[] | null;
getReferences(params: TPICCommonRequestParams): FindReferenceResultItem[] | null;
getDefinitions(params: TPICCommonRequestParams): FindDefinitionsResult | null;
getTypeDefinitions(params: TPICCommonRequestParams): FindDefinitionsResultItem[] | null;
getCompletionInfo(params: GetCompletionsParms): GetCompletionsResult | null;
getCompletionDetail(params: ResolveCompletionParams): ScriptCompletionDetail | null;
getRenameLocations(params: TPICCommonRequestParams): RenameLocationItem[] | null;
getAndConvertPrepareRenameLocation(params: TPICCommonRequestParams): [number, number] | null;
getComponentInfos(fileName: string): ComponentInfo[];
updateQingkuaiFile(params: UpdateContentParams): UpdateContentResult;
ensureGetQingkuaiFileInfo(fileName: string): QingkuaiFileInfo;
}
declare class FileEdit {
private fileInfo;
private updateSourceFile;
private index;
private insertInfo;
items: {
content: string;
sourceRange?: Pair<number>;
}[];
constructor(fileInfo: QingkuaiFileInfo, updateSourceFile: GeneralFunc);
get isEmpty(): boolean;
get editStartIndex(): number;
setEditIndex(index: number): void;
getEditedIndex(index: number): number;
push(content: string, sourceRange?: Pair<number>): void;
flush(): void;
}
declare class QingkuaiFileInfo {
code: string;
isTS: boolean;
version: number;
path: TsNormalizedPath;
getTypeDelayIndexes: number[];
idStatusInfo: Record<string, string>;
private adapter;
private itos;
private stoi;
private positions;
private nextAdjustSourceIndex;
isOpen: boolean;
componentName: string;
typesConfirmed: boolean;
slotNames: string[];
defaultExportTypeStr: string;
lsDiagnostics: LSDiagnostic[];
attributes: ComponentAttributeItem[];
constructor(code: string, isTS: boolean, version: number, path: TsNormalizedPath, getTypeDelayIndexes: number[], idStatusInfo: Record<string, string>, adapter: TypescriptAdapter, itos: number[], stoi: number[], positions: ASTPositionWithFlag[]);
getSourceIndex(interIndex: number): number;
getInterIndex(sourceIndex: number): number;
getPositionByIndex(index: number): ASTPositionWithFlag;
updateContent(newContent: string): void;
confirmTypes(): void;
isPositionFlagSetAtIndex(key: keyof typeof PositionFlag, index: number): boolean;
adjustIndexMap(edit: FileEdit): void;
pushDiagnostic(start: number, end: number, [code, message, link]: LSMessage): void;
}
declare namespace QingkuaiCommandTypes {
interface ShowReferencesParams {
fileName: string;
position: Position;
locations: Location[];
}
}
interface CodeLensConfig {
referencesCodeLens?: {
enabled: boolean;
showOnAllFunctions: boolean;
};
implementationsCodeLens?: {
enabled: boolean;
showOnInterfaceMethods: boolean;
};
}
interface TextEditWithPosRange {
range: Pair<number>;
newText: string;
}
type ScriptCompletionDetail = Omit<TS.CompletionEntryDetails, "documentation" | "codeActions" | "displayParts"> & {
detail: string;
documentation?: string;
codeActions?: (Omit<TS.CodeAction, "changes"> & {
effects: TS.FileTextChanges[];
currentFileChanges: TextEditWithPosRange[];
})[];
};
type GetCodeLensConfigFunc = (uri: string, languageId: string) => MaybePromise<CodeLensConfig>;
type GetScriptHoverFunc = (fileName: string, pos: number) => MaybePromise<HoverTipResult | null>;
type GetScriptBlockSignatureFunc = (fileName: string, pos: number, isRetrigger: boolean, triggerCharacter: SignatureHelpParams["triggerCharacter"]) => MaybePromise<SignatureHelp | null>;
type PrepareRenameInScriptBlockFunc = (cr: CompileResult, pos: number) => MaybePromise<Pair<number> | null>;
type FindScriptDefinitionsFunc = (cr: CompileResult, pos: number) => MaybePromise<FindDefinitionsResult | null>;
type GetScriptCompletionsFunc = (fileName: string, pos: number, triggerCharacter: string, triggerKind: CompletionTriggerKind | undefined) => MaybePromise<GetCompletionsResult | null>;
type RenameInScriptBlockFunc = (fileName: string, pos: number) => MaybePromise<RenameLocationItem[] | null>;
type GetScriptCompletionDetailFunc = (item: CompletionItem) => MaybePromise<ScriptCompletionDetail | null>;
type FindScriptReferencesFunc = (fileName: string, offset: number) => MaybePromise<FindReferenceResultItem[] | null>;
type GetScriptImplementationsFunc = (fileName: string, pos: number) => MaybePromise<FindReferenceResultItem[] | null>;
type DoResolveCodeLensFunc = (fileName: string, pos: number, type: "reference" | "implementation") => MaybePromise<FindReferenceResultItem[] | null>;
type FindScriptTypeDefinitionsFunc = (fileName: string, pos: number) => MaybePromise<FindDefinitionsResultItem[] | null>;
type LSMessage = [number, string, string?];
type PrettierAndPlugins = [typeof Prettier, ...Array<string | Prettier.Plugin>];
type InsertSnippetFunc = (item: string | InsertSnippetParams) => void;
type GetUserPreferencesFunc = (fileName: string) => TS.UserPreferences;
type GetCompileResultFunc = (path: string) => MaybePromise<CompileResult>;
type GetFormattingOptionsFunc = (fileName: string) => TS.FormatCodeSettings;
type ShowReferencesCommandParams = QingkuaiCommandTypes.ShowReferencesParams;
type CompileIntermidiateFunc = (path: string) => CompileIntermediateResult;
type GetCssConfigFunc = (uri: string) => MaybePromise<HoverSettings | undefined>;
type GetComponentInfosFunc = (fileName: string) => MaybePromise<ComponentInfo[]>;
type GetQingkuaiConfigFunc = (fileName: string) => TsPluginQingkuaiConfig | undefined;
type GetScriptNavTreeFunc = (fileName: string) => MaybePromise<TS.NavigationTree | null>;
type UpdateQingkuaiFileContentFunc = (fileInfo: QingkuaiFileInfo, newContent: string) => void;
type GetScriptDiagnosticsFunc = (fileName: string) => MaybePromise<GetDiagnosticResultItem[]>;
export { Logger as L, createLogger as x, QingkuaiFileInfo as y, TypescriptAdapter as z };
export type { AdapterFS as A, CompileResult as C, DoResolveCodeLensFunc as D, FindScriptReferencesFunc as F, GeneralFunc as G, InsertSnippetFunc as I, PromiseWithState as P, QingkuaiConfiguration as Q, RenameInScriptBlockFunc as R, ScriptCompletionDetail as S, TsPluginQingkuaiConfig as T, GetCssConfigFunc as a, GetScriptHoverFunc as b, GetComponentInfosFunc as c, PrettierAndPlugins as d, GetScriptDiagnosticsFunc as e, GetScriptBlockSignatureFunc as f, GetCompileResultFunc as g, PrepareRenameInScriptBlockFunc as h, GetScriptCompletionsFunc as i, GetScriptImplementationsFunc as j, GetScriptNavTreeFunc as k, GetCodeLensConfigFunc as l, GetScriptCompletionDetailFunc as m, FindScriptDefinitionsFunc as n, FindScriptTypeDefinitionsFunc as o, AdapterPath as p, AdapterTsProject as q, AdapterTsProjectService as r, CompileIntermidiateFunc as s, ComponentAttributeItem as t, ComponentInfo as u, InsertSnippetParams as v, ShowReferencesCommandParams as w };