@sap/cds-lsp
Version:
Language server for CDS
638 lines (635 loc) • 19.2 kB
TypeScript
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_join(...paths: string[]): AbsolutePath;
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 type XsnDependencies = Array<{
location: XsnLocation;
val: UsingPath;
}>;
export interface XsnParseModel {
dependencies?: XsnDependencies;
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;
withCst?: boolean;
}
export interface CdscCompileOptions {
fallbackParser?: "cds";
attachValidNames?: boolean;
attachTokens?: boolean;
lspMode?: boolean;
docComment?: boolean;
messages?: XsnMessage[];
parseListener?: unknown;
newParser?: boolean;
abortSignal?: AbortSignal;
}
export interface ModuleOrigin {
__loadedFrom: AbsolutePath;
__logicalLocation: string;
}
export interface ICdsCompiler extends ModuleOrigin {
parse(source: FileContent, filename: string, options?: CdscParseOptions): XsnParseModel;
parse(source: FileContent, filename: string, options: CdscParseOptions & {
withCst: true;
}): XsnParseModel;
compile(fileNames: AbsolutePath[], dir?: AbsolutePath, options?: CdscCompileOptions, map?: CdscFileMap): Promise<XsnCompileModel>;
version(): string;
$lsp: ICdsCompiler;
explainMessage: (messageId: string) => string | undefined;
getMessageExplanationUri: (messageId: string) => Uri | undefined;
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;
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;
usingsOf(source: XsnSource): XsnArtifactUsing[];
getSemanticTokenOrigin(o: XsnReferenceEvent): XsnArtifact[];
getDefinitionOrigin(o: XsnDefinitionEvent): unknown[];
getAnnotationParseTrees(o: any): XsnAnnotationAssignment[];
toLspLocation(csnLocation: XsnLocation): CdsLocation;
}
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 XsnFakeCompileModel extends XsnCompileModel {
fakeInlay: string;
}
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: UsingPath;
}
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;
_parent: XsnArtifact;
localized?: {
location: XsnLocation;
val: unknown;
};
}
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" | "namespace-statement";
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;
token?: 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 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 IGenericDefinition {
readonly symbolName: FullyQualifiedName;
readonly fullyQualifiedName: FullyQualifiedName;
readonly kind: XsnKind;
readonly absoluteName: FullyQualifiedName;
}
export interface IIdentifierToken extends IGenericToken {
}
export interface IFileIndex {
directDependentUris: FileUri[];
readonly annotationAssignments: IterableIterator<IAnnotationAssignmentToken>;
readonly content: FileContent;
readonly tokens: IToken[];
}
export interface IToken extends LSP.Position {
readonly text: string;
startOffset: number;
readonly endOffset: number;
readonly line: number;
readonly character: number;
readonly endLine: number;
readonly endCharacter: number;
readonly tokenIndex: number;
isIdentifier(): boolean;
isOperator(): boolean;
isKeyword(): boolean;
isStringLiteral(): boolean;
isComment(): boolean;
}
export interface IExplicitDefinition extends IGenericDefinition, LSP.Position {
location: CdsLocation;
nameLocation: CdsLocation;
line: number;
character: number;
docComment?: string;
}
export interface IBlitzIndex {
readonly builtUris: readonly Uri[];
getTransitiveDependencies(uri: Uri): Set<Uri>;
forUri(uri: Uri, create?: undefined | "create" | "warnCreate"): IFileIndex;
forUri(uri: Uri, 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;
signal?: AbortSignal;
}
export interface CdsAnnotationIndexEntry {
absoluteName: string;
definition: CdsLocation;
references: CdsLocation[];
}
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;
signal?: AbortSignal;
}
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 {};