UNPKG

@sap/cds-lsp

Version:

Language server for CDS

615 lines (612 loc) 18.8 kB
import * as LSP from 'vscode-languageserver-protocol'; export type SpecificString<T> = string & { _brand: T; }; export type FileUri = `file:///${string}`; export type UntitledUri = `untitled:${string}`; export type Uri = FileUri | UntitledUri; export type AbsolutePath = `/${string}`; export type RelativePath = `./${string}` | `../${string}`; export type FileContent = SpecificString<"FileContent">; export type Markdown = SpecificString<"Markdown">; export type WorkspaceRelativePath = SpecificString<"WorkspaceRelativePath">; export declare const EMPTY_FILE_CONTENT: FileContent; export type UsingPath = SpecificString<"UsingPath">; export declare function path_isAbsolute(p: string): p is AbsolutePath; export declare function path_dirname(p: AbsolutePath): AbsolutePath; export declare function path_resolve(...paths: string[]): AbsolutePath; export declare function path_relative(from: AbsolutePath, to: AbsolutePath): RelativePath; export declare function path_normalize<T extends AbsolutePath | RelativePath>(p: T): T; export declare function process_cwd(): AbsolutePath; export declare const UNKNOWN_NAME = ""; export type XsnKind = "__i18n" | "$parameters" | "action" | "annotate" | "annotation" | "aspect" | "builtin" | "context" | "element" | "entity" | "enum" | "event" | "extend" | "function" | "key" | "mixin" | "namespace" | "param" | "qualifiedAnnotation" | "select" | "service" | "source" | "type" | "using" | "view" | "$tableAlias"; export interface Thing { kind: XsnKind; name: XsnBaseName; location: XsnLocation; _artifact?: XsnArtifact; value?: XsnExtensionName; $duplicates?: boolean | Thing[]; } export interface XsnValidName { kind: XsnKind; name: { absolute: string; id?: string; }; location: XsnLocation; builtin?: boolean; parameters?: string[]; } export type XsnSeverity = "Error" | "Warning" | "Info" | "Debug"; export interface XsnParseModel { dependencies?: Array<{ location: XsnLocation; val: UsingPath; }>; usings?: Array<{ location: XsnLocation; fileDep?: { location: XsnLocation; val: UsingPath; }; }>; options: CdscParseOptions; tokens: unknown[]; ruleTree: unknown; toolbox: IXsnToolbox; name: { id: string; }; kind: XsnKind; annotationAssignments?: XsnAnnotationAssignment[]; } export interface CdscParseOptions { parseOnly?: boolean; lintMode?: boolean; attachTokens?: boolean; ambigDetection?: boolean; fallbackParser?: string; messages: XsnMessage[]; parseListener?: unknown; newParser?: boolean; } export interface CdscCompileOptions { fallbackParser?: "cds"; attachValidNames?: boolean; attachTokens?: boolean; lspMode?: boolean; docComment?: boolean; messages?: XsnMessage[]; parseListener?: unknown; newParser?: boolean; } export interface ModuleOrigin { __loadedFrom: AbsolutePath; __logicalLocation: string; } export interface ICdsCompiler extends ModuleOrigin { parse(source: FileContent, filename: string, options?: CdscParseOptions): XsnParseModel; compile(fileNames: AbsolutePath[], dir?: AbsolutePath, options?: CdscCompileOptions, map?: CdscFileMap): Promise<XsnCompileModel>; version(): string; $lsp: ICdsCompiler; getArtifactName(thing: unknown): any; getSpecialFunctions?(): string[]; createToolbox(adapter: unknown): IXsnToolbox; traverseSemanticTokens?(model: XsnCompileModel, options: unknown): Generator<XsnIteratorEvent>; getSemanticTokenOrigin(o: XsnIteratorEvent): Generator<XsnArtifact>; } export interface CdscFileMap { [localPath: AbsolutePath]: FileContent; } export interface XsnArtifacts { [localName: string]: XsnArtifact; } export interface XsnElements { [localName: string]: XsnElement; } export interface XsnSources { [absoluteLocalPath: AbsolutePath]: XsnSource; } export interface XsnCompileException { model?: XsnCompileModel; messages?: XsnMessage[]; errors?: Array<{ message: string; }>; } export type ResolutionStep = "ToDefinition" | "ToNextExplicitAlias"; export interface ResolutionOptions { step: ResolutionStep; } export interface IXsnToolbox { toUri(localPath: WorkspaceRelativePath | AbsolutePath): Uri; resolve(thing: any, options?: ResolutionOptions): any[]; nameLocation(thing: any): XsnLocation | undefined; absoluteNameOf(thing: Thing | XsnName | undefined, identifierCategory?: unknown): string | typeof UNKNOWN_NAME; getArtifactName(thing: unknown): any; locationOf(thing: any): XsnLocation; originOf(thing: any): any; getKind(thing: Thing): XsnKind; expectedKindOf(thing: Thing): XsnKind; nameLocationOf(thing: any): XsnLocation | undefined; filterMessagesInScope(position: LSP.Position, message: XsnMessage, relativeProvokerPosition: number): boolean; sourcesOf(ast: XsnCompileModel): XsnSources; isAutoexposed(thing: any): boolean; name(thing: unknown): XsnName; isReturnsCarrier(thing: any): boolean; usingsOf(source: XsnSource): XsnArtifactUsing[]; getSemanticTokenOrigin(o: XsnReferenceEvent): XsnArtifact[]; getDefinitionOrigin(o: XsnDefinitionEvent): unknown[]; getAnnotationParseTrees(o: any): XsnAnnotationAssignment[]; } export interface XsnCompileModel { definitions: XsnArtifacts; sources: XsnSources; version: { creator: string; csn: string; }; options: CdscCompileOptions & { messages: XsnMessage[]; }; workspaceRoot: AbsolutePath; rootFile: AbsolutePath; compilerVersion: string; compiler: ICdsCompiler; toolbox: IXsnToolbox; } export interface XsnMessage { home?: string; message: string; messageId?: string; expectedTokens?: string[]; validNames?: { [id: string]: XsnValidName; }; $location: XsnLocation; severity: XsnSeverity; } export interface XsnSource { vocabularies?: XsnArtifacts; kind: "source"; filename: WorkspaceRelativePath; dirname: AbsolutePath; realname: AbsolutePath; artifacts: XsnArtifacts; dependencies: XsnFileDependency[]; usings: XsnArtifactUsing[]; tokens: unknown[]; ruleTree?: unknown; options: CdscCompileOptions; namespace?: XsnSourceNamespace; } export type XsnNamespacePath = Array<{ id: string; location: XsnLocation; }>; export interface XsnSourceNamespace { path: XsnNamespacePath; } export type DollarInferred = "*" | "autoexposed" | "localized" | "localized-entity"; export interface XsnArtifact { doc?: XsnDocComment; kind: XsnKind; extern?: { location: XsnLocation; path: XsnPathSegment[]; _artifact?: XsnArtifact; }; location: XsnLocation; name: XsnName; elements?: XsnElements; returns?: any; params?: XsnElements; $inferred?: DollarInferred; builtin?: boolean; _main?: XsnArtifact; } export interface XsnAnnotationAssignment { kind?: "annotate"; location: XsnLocation; name: XsnExtensionName; value?: AnnotationValue; val?: string; path?: XsnPathSegment[]; } export interface XsnFileDependency { literal: string; location: XsnLocation; realname?: AbsolutePath; val: string; } export interface XsnDocComment { val: string; location: XsnLocation; } export interface XsnElement { doc?: XsnDocComment; kind: "element"; elements?: XsnElements; location: XsnLocation; name: XsnElementName; type: XsnExtensionElementType; target?: XsnExtensionElementType; returns?: XsnExtensionElementType; $inferred?: DollarInferred; } export interface XsnElementName { absolute: string; element: string; id: string; location: XsnLocation; } export interface XsnExtensionElementType { absolute: string; location: XsnLocation; path: XsnPathSegment[]; scope: number; _artifact?: Thing; } export interface XsnArtifactUsing { kind: "using"; annotationAssignments: XsnAnnotationAssignment[]; extern: { id: FullyQualifiedName; location: XsnLocation; path: XsnPathSegment[]; _artifact?: XsnArtifact; }; location: XsnLocation; name: XsnName; fileDep?: XsnFileDependency; usings?: XsnArtifactUsing[]; } export interface XsnBaseName { absolute: string; id: string; $inferred?: DollarInferred; location: XsnLocation; path?: XsnPathSegment[]; } export interface XsnExtensionName extends XsnBaseName { location: XsnLocation; path: XsnPathSegment[]; _artifact?: Thing; } export interface XsnName extends XsnBaseName { absolute: string; calculated?: boolean; action?: string; param?: string; element?: string; id: string; $inferred?: DollarInferred; location: XsnLocation; path?: XsnPathSegment[]; query?: number; _artifact?: Thing; } export interface XsnTokenReference { id: string; location: XsnLocation; _artifact: XsnArtifact; } export type XsnIteratorHint = "using-alias"; export interface XsnDefinitionEvent { hint?: XsnIteratorHint; node: XsnArtifact; event: "definition"; semanticToken: XsnTokenReference; } export interface XsnReferenceEvent { hint?: XsnIteratorHint; node: XsnExpression | XsnArtifact; event: "reference"; semanticToken: XsnTokenReference; } export type XsnIteratorEvent = XsnDefinitionEvent | XsnReferenceEvent; export interface XsnExpression { path?: object[]; _artifact?: XsnArtifact; } export interface XsnLocation { file: WorkspaceRelativePath; line: number; col: number; endLine: number; endCol: number; tokenIndex?: number; } export interface XsnPathSegment { id: string; location: XsnLocation; _artifact?: Thing; } export interface IXsnUsingExtraction { getUsingLocation(tokens: unknown[]): LSP.Range; getTargetFilePath(): AbsolutePath | WorkspaceRelativePath | undefined; getTargetImportPath(): UsingPath | undefined; getImportedItems(): IXsnImportedItem[]; } export interface IXsnImportedItem { getItemImportLocation(): XsnLocation; getAbsoluteName(): FullyQualifiedName; getLocalName(): string; getAbsoluteNameLocation(): XsnLocation; getLocalNameLocation(): XsnLocation; getTargetFilePath(): WorkspaceRelativePath | undefined; } export type FullyQualifiedName = string; export interface IXsnDefinitionEvent { thing: any; fullyQualifiedName: FullyQualifiedName; hint?: "compilerAPI"; name?: any; } export interface IXsnReferenceEvent { model: XsnCompileModel; thing: any; hint?: string; } export interface AnnotationValueBase { location: XsnLocation; name?: Name; } export interface Name { location: XsnLocation; path: XsnNameSegment3[]; variant?: Omit<Name, "variant">; } export interface LeafName extends Name { absolute?: string; } export interface NonLeafAnnotationValue extends AnnotationValueBase { $flatten?: AnnotationValue[]; } export interface LeafAnnotationValue extends AnnotationValueBase { $priority?: "annotate"; literal?: "string" | "number" | "enum" | "array" | "struct" | "hex" | "null" | "boolean" | "date" | "time" | "timestamp"; _block?: any; } export interface NamedLeafAnnotationValue extends LeafAnnotationValue { name: LeafName; } export interface StringValue extends NamedLeafAnnotationValue { literal: "string"; val: string; } export interface NumberValue extends NamedLeafAnnotationValue { literal: "number"; val: number | string; } export interface EnumValue extends NamedLeafAnnotationValue { literal: "enum"; sym: XsnNameSegment3; } export interface ArrayValue extends NamedLeafAnnotationValue { literal: "array"; val: AnnotationValue[]; } export interface StructValue extends AnnotationValueBase { literal: "struct"; struct: { [id: string]: AnnotationValue; }; } export interface HexValue extends NamedLeafAnnotationValue { literal: "hex"; val: `${HexChar}${HexChar}${HexChar}${HexChar}`; } export interface NullValue extends NamedLeafAnnotationValue { literal: "null"; val: null; } export interface BooleanValue extends NamedLeafAnnotationValue { literal: "boolean"; val: true | false; } export interface DateValue extends NamedLeafAnnotationValue { literal: "date"; val: DateYMDString; } export interface TimeValue extends NamedLeafAnnotationValue { literal: "time"; val: Time; } export interface TimestampValue extends NamedLeafAnnotationValue { literal: "timestamp"; val: string; } export type AnyAnnotationLeafValue = NullValue | BooleanValue | NumberValue | StringValue | DateValue | TimeValue | TimestampValue | HexValue | EnumValue | ArrayValue | StructValue; export type AnnotationValue = NonLeafAnnotationValue | AnyAnnotationLeafValue; export type OneToNine = 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9; export type ZeroOrOne = 0 | 1; export type ZeroToThree = 0 | 1 | 2 | 3; export type ZeroToFive = 0 | 1 | 2 | 3 | 4 | 5; export type d = OneToNine | 0; export type YYYY = `19${d}${d}` | `20${d}${d}`; export type DD = `${0}${OneToNine}` | `${1 | 2}${d}` | `3${ZeroOrOne}`; export type MM = `0${OneToNine}` | `1${0 | 1 | 2}`; export type HH = `${ZeroOrOne}${OneToNine}` | `2${ZeroToThree}`; export type MinSec = `${ZeroToFive}${d}`; export type HexLet = "a" | "b" | "c" | "d" | "e" | "f"; export type HexChar = d | HexLet; export type DateYMString = `${YYYY}-${MM}`; export type DateYMDString = `${DateYMString}-${DD}`; export type Time = `${HH}:${MinSec}:${MinSec}`; export interface XsnNameSegment3 { id: string; location: XsnLocation; } export interface CdsLocation extends LSP.Location { uri: Uri; } export type AutoCreationMode = "create" | "noCreate" | "warnCreate"; export interface IAnnotationAssignmentToken extends IGenericToken { readonly carrier: IIdentifierToken; readonly carrierName: string; readonly carrierNameRange?: LSP.Range; } export interface IGenericToken extends LSP.Position { readonly uri: Uri; readonly tokenIndex: number; readonly text: string; readonly annotationValue?: string; readonly range: LSP.Range; readonly location: LSP.Location; readonly start: LSP.Position; readonly end: LSP.Position; isIdentifier(): this is IIdentifierToken; isKeyword(): boolean; compare(position: LSP.Position): number; } export interface IStringLiteralToken extends IGenericToken { translationId?: string; isUsingPath?: boolean; } export interface ITranslationStringToken extends IStringLiteralToken { translationId: string; } export declare function isTranslationStringToken(token: IStringLiteralToken): token is ITranslationStringToken; export interface IImportPathStringToken extends IStringLiteralToken { isUsingPath: true; } export declare function isImportPathStringToken(token: IStringLiteralToken): token is IImportPathStringToken; export interface IGenericDefinition { readonly symbolName: FullyQualifiedName; readonly fullyQualifiedName: FullyQualifiedName; readonly kind: XsnKind; readonly absoluteName: FullyQualifiedName; } export interface IIdentifierToken extends IGenericToken { readonly definitions?: IGenericDefinition | IGenericDefinition[]; } export interface IFileIndex { idTokens: IIdentifierToken[]; directDependentUris: FileUri[]; readonly annotationAssignments: IterableIterator<IAnnotationAssignmentToken>; } export interface IExplicitDefinition extends IGenericDefinition, LSP.Position { location: CdsLocation; nameLocation: CdsLocation; line: number; character: number; docComment?: string; isExtend?: boolean; isAspect?: boolean; } export interface IBlitzIndex { readonly builtUris: readonly string[]; getTransitiveDependencies(uri: string): Set<string>; forUri(uri: string, create?: undefined | "create" | "warnCreate"): IFileIndex; forUri(uri: string, create: "noCreate"): IFileIndex | undefined; } export interface IContribution { initialize?: (context: IContributionContext) => Promise<void>; } export declare enum Setting { MarkMissingTranslations = "cds.compiler.markMissingI18nDefault", OmitRedundantTypesInSnippets = "cds.completion.annotations.omitRedundantTypesInSnippets", EnableAdditionalAnalyticalAnnotations = "cds.contributions.enablement.additionalAnalyticalAnnotations" } export interface Translation { uri: FileUri; line: number; character: number; id: string; text: string; } export interface ITranslationProvider { resolve(sourceUri: string, translationId: string): Translation | undefined; } export interface ISettingsProvider { get(setting: Setting): unknown; } export interface IContributionContext { trace: IContributionTracer; translation: ITranslationProvider; settings: ISettingsProvider; } export type ContributionTraceMessage = () => string; export interface IContributionTracer { debug(m: ContributionTraceMessage): void; verbose(m: ContributionTraceMessage): void; info(m: ContributionTraceMessage): void; warn(m: ContributionTraceMessage): void; error(m: ContributionTraceMessage): void; } export interface IAnnotationContribution extends IContribution { fetchCompletions?: (params: CdsCompletionParams) => Promise<CdsCompletionItem[]>; fetchDiagnostics?: (params: CdsDiagnosticParams) => Promise<CdsDiagnostics>; fetchQuickfixes?: (params: LSP.CodeActionParams) => Promise<CdsQuickfix[]>; fetchHover?: (params: CdsHoverParams) => Promise<CdsHover | undefined>; fetchDefinition?: (params: CdsDefinitionParams) => Promise<CdsLocation | CdsLocation[] | undefined>; fetchReferences?: (params: CdsDefinitionParams) => Promise<CdsLocation[]>; fetchSemanticTokens?: (params: CdsSemanticTokensParams) => Promise<SemanticToken[]>; indexAnnotationIdentifiers?: (params: CdsIndexingParams) => Promise<CdsAnnotationIndex>; indexAndValidate?: (params: CdsIndexingParams) => Promise<CdsAnnotationIndexAndDiagnostics>; } export interface CdsIndexingParams { uris: Uri[]; index: IBlitzIndex; ast: XsnCompileModel; } export interface CdsAnnotationIndexEntry { absoluteName: string; definition: LSP.Location; references: LSP.Location[]; } export type CdsDiagnostics = Map<Uri, LSP.Diagnostic[]>; export type CdsAnnotationIndex = CdsAnnotationIndexEntry[]; export interface CdsAnnotationIndexAndDiagnostics { annotationIndex: CdsAnnotationIndex; diagnostics: CdsDiagnostics; } export type CdsQuickfix = Omit<LSP.CodeAction, "command">; export interface CdsCompletionParams { cursorPosition: LSP.TextDocumentPositionParams; index: IBlitzIndex; annotation: IAnnotationAssignmentToken; ast: XsnCompileModel; relativeLocalPath: string; isCompoundAnnotation: boolean; completionItemsFromCompiler: LSP.CompletionItem[]; } export interface CdsDiagnosticParams { uris: Uri[]; index: IBlitzIndex; ast: XsnCompileModel; } export interface CdsHoverParams { cursorPosition: LSP.TextDocumentPositionParams; annotation: IAnnotationAssignmentToken; index: IBlitzIndex; } export interface CdsDefinitionParams { cursorPosition: LSP.TextDocumentPositionParams; annotation: IAnnotationAssignmentToken; index: IBlitzIndex; ast: XsnCompileModel; } export interface CdsHover extends LSP.Hover { contents: CdsMarkupContent; } export interface CdsMarkupContent extends LSP.MarkupContent { kind: "markdown"; } export interface CdsCompletionItem extends LSP.CompletionItem { data?: unknown; } export interface CdsSemanticTokensParams { uri: Uri; index: IBlitzIndex; } export interface SemanticToken { line: number; character: number; length: number; tokenType: LSP.SemanticTokenTypes; tokenModifiers: LSP.SemanticTokenModifiers[]; } export {};