From 00063fe257b5a356cd881f337ae6676c078e12a7 Mon Sep 17 00:00:00 2001 From: Roberto Raggi Date: Wed, 23 Oct 2024 20:54:47 +0200 Subject: [PATCH] chore: Initial work on LSP support --- package-lock.json | 23 + package.json | 6 +- packages/cxx-gen-lsp/.eslintrc.json | 14 + packages/cxx-gen-lsp/.gitignore | 3 + packages/cxx-gen-lsp/package.json | 36 + packages/cxx-gen-lsp/src/MetaModel.ts | 91 +++ packages/cxx-gen-lsp/src/copyrightHeader.ts | 19 + packages/cxx-gen-lsp/src/gen_enums_cc.ts | 68 ++ packages/cxx-gen-lsp/src/gen_enums_h.ts | 74 +++ packages/cxx-gen-lsp/src/main.ts | 87 +++ packages/cxx-gen-lsp/tsconfig.json | 12 + scripts/download-lsp-model.mjs | 60 ++ src/CMakeLists.txt | 1 + src/lsp/CMakeLists.txt | 49 ++ src/lsp/cxx/lsp/enums.cc | 703 ++++++++++++++++++++ src/lsp/cxx/lsp/enums.h | 417 ++++++++++++ 16 files changed, 1661 insertions(+), 2 deletions(-) create mode 100644 packages/cxx-gen-lsp/.eslintrc.json create mode 100644 packages/cxx-gen-lsp/.gitignore create mode 100644 packages/cxx-gen-lsp/package.json create mode 100644 packages/cxx-gen-lsp/src/MetaModel.ts create mode 100644 packages/cxx-gen-lsp/src/copyrightHeader.ts create mode 100644 packages/cxx-gen-lsp/src/gen_enums_cc.ts create mode 100644 packages/cxx-gen-lsp/src/gen_enums_h.ts create mode 100644 packages/cxx-gen-lsp/src/main.ts create mode 100644 packages/cxx-gen-lsp/tsconfig.json create mode 100644 scripts/download-lsp-model.mjs create mode 100644 src/lsp/CMakeLists.txt create mode 100644 src/lsp/cxx/lsp/enums.cc create mode 100644 src/lsp/cxx/lsp/enums.h diff --git a/package-lock.json b/package-lock.json index e8785bfb..b0e42226 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1397,6 +1397,10 @@ "resolved": "packages/cxx-gen-ast", "link": true }, + "node_modules/@robertoraggi/cxx-gen-lsp": { + "resolved": "packages/cxx-gen-lsp", + "link": true + }, "node_modules/@robertoraggi/cxx-storybook": { "resolved": "packages/cxx-storybook", "link": true @@ -8962,6 +8966,25 @@ "typescript": "^5.6.3" } }, + "packages/cxx-gen-lsp": { + "name": "@robertoraggi/cxx-gen-lsp", + "version": "1.0.0", + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "prettier": "^3.3.3" + }, + "bin": { + "cxx-gen-lsp": "dist/main.js" + }, + "devDependencies": { + "@types/node": "^22.7.5", + "@typescript-eslint/eslint-plugin": "^8.9.0", + "@typescript-eslint/parser": "^8.9.0", + "eslint": "^9.12.0", + "typescript": "^5.6.3" + } + }, "packages/cxx-storybook": { "name": "@robertoraggi/cxx-storybook", "version": "0.0.0", diff --git a/package.json b/package.json index ae2fd4f6..1c587cfa 100644 --- a/package.json +++ b/package.json @@ -37,6 +37,8 @@ "storybook": "npm run storybook -w @robertoraggi/cxx-storybook", "setup-venv": "zx scripts/setup-venv.mjs", "update-tests": "zx scripts/update-tests.mjs", - "cxx-gen-ast": "node packages/cxx-gen-ast" + "cxx-gen-ast": "node packages/cxx-gen-ast", + "cxx-gen-lsp": "node packages/cxx-gen-lsp packages/cxx-gen-lsp/metaModel.json packages/cxx-gen-lsp -o src/lsp/cxx/lsp", + "download-lsp-models": "zx scripts/download-lsp-models.mjs" } -} +} \ No newline at end of file diff --git a/packages/cxx-gen-lsp/.eslintrc.json b/packages/cxx-gen-lsp/.eslintrc.json new file mode 100644 index 00000000..380b4171 --- /dev/null +++ b/packages/cxx-gen-lsp/.eslintrc.json @@ -0,0 +1,14 @@ +{ + "env": { + "browser": true, + "es2021": true + }, + "extends": ["eslint:recommended", "plugin:@typescript-eslint/recommended"], + "parser": "@typescript-eslint/parser", + "parserOptions": { + "ecmaVersion": "latest", + "sourceType": "module" + }, + "plugins": ["@typescript-eslint"], + "rules": {} +} diff --git a/packages/cxx-gen-lsp/.gitignore b/packages/cxx-gen-lsp/.gitignore new file mode 100644 index 00000000..9c19077d --- /dev/null +++ b/packages/cxx-gen-lsp/.gitignore @@ -0,0 +1,3 @@ +node_modules/ +dist/ +metaModel.json \ No newline at end of file diff --git a/packages/cxx-gen-lsp/package.json b/packages/cxx-gen-lsp/package.json new file mode 100644 index 00000000..29c53613 --- /dev/null +++ b/packages/cxx-gen-lsp/package.json @@ -0,0 +1,36 @@ +{ + "name": "@robertoraggi/cxx-gen-lsp", + "version": "1.0.0", + "private": true, + "type": "module", + "description": "Scripts to generate the LSP server for C++", + "main": "./dist/main.js", + "bin": { + "cxx-gen-lsp": "./dist/main.js" + }, + "scripts": { + "postinstall": "npm run build", + "build": "tsc", + "watch": "tsc -w" + }, + "keywords": [], + "author": { + "name": "Roberto Raggi", + "email": "roberto.raggi@gmail.com" + }, + "repository": { + "type": "git", + "url": "https://github.com/robertoraggi/cplusplus" + }, + "license": "MIT", + "devDependencies": { + "@types/node": "^22.7.5", + "@typescript-eslint/eslint-plugin": "^8.9.0", + "@typescript-eslint/parser": "^8.9.0", + "eslint": "^9.12.0", + "typescript": "^5.6.3" + }, + "dependencies": { + "prettier": "^3.3.3" + } +} \ No newline at end of file diff --git a/packages/cxx-gen-lsp/src/MetaModel.ts b/packages/cxx-gen-lsp/src/MetaModel.ts new file mode 100644 index 00000000..2941d350 --- /dev/null +++ b/packages/cxx-gen-lsp/src/MetaModel.ts @@ -0,0 +1,91 @@ +// Copyright (c) 2024 Roberto Raggi +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +export type Type = BaseType; + +export type BaseTypeName = "string" | "integer" | "uinteger"; + +export type BaseType = { + kind: "base"; + name: BaseTypeName; +}; + +export type EnumerationValue = { + name: string; + value: string; +}; + +export type MetaData = {}; + +export type Enumeration = { + documentation?: string; + name: string; + since?: string; + supportsCustomValues?: boolean; + type: BaseType; + values: EnumerationValue[]; +}; + +export type Notification = {}; + +export type Request = {}; + +export type Structure = {}; + +export type TypeAlias = {}; + +export type MetaModel = { + metaData: MetaData; + enumerations: Enumeration[]; + notifications: Notification[]; + requests: Request[]; + structures: Structure[]; + typeAliases: TypeAlias[]; +}; + +export function getEnumBaseType(enumeration: Enumeration) { + switch (enumeration.type.name) { + case "integer": + return " : int"; + case "uinteger": + return " : unsigned int"; + default: + return ""; + } +} + +export function toUpperCamelCase(name: string) { + return name[0].toUpperCase() + name.slice(1); +} + +export function getEnumeratorName(enumerator: EnumerationValue) { + const name = toUpperCamelCase(enumerator.name); + return `k${name}`; +} + +export function getEnumeratorInitializer( + enumeration: Enumeration, + enumerator: EnumerationValue +) { + if (enumeration.type.name === "string") { + return ""; + } + return ` = ${enumerator.value}`; +} diff --git a/packages/cxx-gen-lsp/src/copyrightHeader.ts b/packages/cxx-gen-lsp/src/copyrightHeader.ts new file mode 100644 index 00000000..a15e596a --- /dev/null +++ b/packages/cxx-gen-lsp/src/copyrightHeader.ts @@ -0,0 +1,19 @@ +export const copyrightHeader = `// Copyright (c) 2024 Roberto Raggi +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE.`; diff --git a/packages/cxx-gen-lsp/src/gen_enums_cc.ts b/packages/cxx-gen-lsp/src/gen_enums_cc.ts new file mode 100644 index 00000000..b08f344d --- /dev/null +++ b/packages/cxx-gen-lsp/src/gen_enums_cc.ts @@ -0,0 +1,68 @@ +// Copyright (c) 2024 Roberto Raggi +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +import { getEnumeratorName, MetaModel } from "./MetaModel.js"; + +import path from "node:path"; +import { writeFile } from "node:fs/promises"; +import { copyrightHeader } from "./copyrightHeader.js"; + +export async function gen_enums_cc({ + model, + outputDirectory, +}: { + model: MetaModel; + outputDirectory: string; +}) { + let out = ""; + + const emit = (s: string = "") => { + out += `${s}\n`; + }; + + emit(`#include `); + emit(); + emit(`namespace cxx::lsp {`); + + model.enumerations.forEach((enumeration) => { + emit(); + emit(`auto to_string(${enumeration.name} value) -> std::string {`); + emit(` switch (value) {`); + + enumeration.values.forEach((enumerator) => { + const enumeratorName = getEnumeratorName(enumerator); + + const text = + enumeration.type.name === "string" ? enumerator.value : enumerator.name; + + emit(` case ${enumeration.name}::${enumeratorName}:`); + emit(` return "${text}";`); + }); + + emit(` }`); + emit(`}`); + }); + + emit(); + emit(`} // namespace cxx::lsp`); + + const outputFile = path.join(outputDirectory, "enums.cc"); + await writeFile(outputFile, out); +} diff --git a/packages/cxx-gen-lsp/src/gen_enums_h.ts b/packages/cxx-gen-lsp/src/gen_enums_h.ts new file mode 100644 index 00000000..480be8c9 --- /dev/null +++ b/packages/cxx-gen-lsp/src/gen_enums_h.ts @@ -0,0 +1,74 @@ +// Copyright (c) 2024 Roberto Raggi +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +import { + getEnumBaseType, + getEnumeratorInitializer, + getEnumeratorName, + MetaModel, +} from "./MetaModel.js"; + +import path from "node:path"; +import { writeFile } from "node:fs/promises"; + +export async function gen_enums_h({ + model, + outputDirectory, +}: { + model: MetaModel; + outputDirectory: string; +}) { + let out = ""; + + const emit = (s: string = "") => { + out += `${s}\n`; + }; + + emit(`#pragma once`); + emit(); + emit(); + emit(`#include `); + emit(); + emit(`namespace cxx::lsp {`); + + model.enumerations.forEach((enumeration) => { + emit(); + const enumBaseType = getEnumBaseType(enumeration); + emit(`enum class ${enumeration.name}${enumBaseType} {`); + enumeration.values.forEach((value) => { + const enumeratorName = getEnumeratorName(value); + const enumeratorInitializer = getEnumeratorInitializer( + enumeration, + value + ); + emit(` ${enumeratorName}${enumeratorInitializer},`); + }); + emit(`};`); + }); + emit(); + model.enumerations.forEach((enumeration) => { + emit(`auto to_string(${enumeration.name} value) -> std::string;`); + }); + emit(); + emit(`} // namespace cxx::lsp`); + + const outputFile = path.join(outputDirectory, "enums.h"); + await writeFile(outputFile, out); +} diff --git a/packages/cxx-gen-lsp/src/main.ts b/packages/cxx-gen-lsp/src/main.ts new file mode 100644 index 00000000..e25b0679 --- /dev/null +++ b/packages/cxx-gen-lsp/src/main.ts @@ -0,0 +1,87 @@ +// Copyright (c) 2024 Roberto Raggi +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +import * as process from "node:process"; +import * as child_process from "node:child_process"; +import { parseArgs } from "node:util"; +import { readFile, mkdir } from "node:fs/promises"; +import { MetaModel } from "./MetaModel.js"; +import { gen_enums_h } from "./gen_enums_h.js"; +import { gen_enums_cc } from "./gen_enums_cc.js"; + +async function main() { + try { + const args = parseArgs({ + args: process.argv.slice(2), + allowPositionals: true, + options: { + output: { + type: "string", + short: "o", + description: "Output directory", + }, + }, + }); + + const { positionals } = args; + const { output: outputDirectory } = args.values; + + const input = positionals[0]; + + if (!input) { + throw new Error("Path to the LSP metaModel.json is required"); + } + + if (!outputDirectory) { + throw new Error("Output directory is required"); + } + + const modelSource = await readFile(input, "utf-8"); + const model = JSON.parse(modelSource) as MetaModel; + + await mkdir(outputDirectory, { recursive: true }); + + await gen_enums_h({ outputDirectory, model }); + await gen_enums_cc({ outputDirectory, model }); + + console.log( + child_process + .execSync("clang-format --verbose -i *.h *.cc", { + cwd: outputDirectory, + }) + .toString() + ); + } catch (error) { + if (error instanceof Error) { + console.error(`${error.message}\n`); + } + + console.error( + "usage: cxx-gen-lsp --output output-directory " + ); + + process.exit(1); + } +} + +main().catch((error) => { + console.error(error); + process.exit(1); +}); diff --git a/packages/cxx-gen-lsp/tsconfig.json b/packages/cxx-gen-lsp/tsconfig.json new file mode 100644 index 00000000..c4078f55 --- /dev/null +++ b/packages/cxx-gen-lsp/tsconfig.json @@ -0,0 +1,12 @@ +{ + "compilerOptions": { + "module": "NodeNext", + "target": "ESNext", + "moduleResolution": "NodeNext", + "outDir": "dist", + "skipLibCheck": true, + "strict": true, + "sourceMap": true + }, + "exclude": ["node_modules"] +} diff --git a/scripts/download-lsp-model.mjs b/scripts/download-lsp-model.mjs new file mode 100644 index 00000000..998b220c --- /dev/null +++ b/scripts/download-lsp-model.mjs @@ -0,0 +1,60 @@ +#!/usr/bin/env zx + +// Copyright (c) 2024 Roberto Raggi +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +import { writeFile } from "node:fs/promises"; +import * as path from "node:path"; + +$.verbose = true; + +// Current working directory computed related to the script location +const workspaceDir = path.join(__dirname, "../"); + +async function main() { + const url = + "https://raw.githubusercontent.com/microsoft/vscode-languageserver-node/refs/heads/main/protocol/metaModel.json"; + + const response = await fetch(url); + + const json = await response.json(); + + const model = JSON.stringify(json, null, 2); + + const outputPath = path.join( + workspaceDir, + "packages/cxx-gen-lsp/metaModel.json" + ); + + echo`Writing model to ${outputPath}`; + + await writeFile(outputPath, model); +} + +main().catch((e) => { + if (e instanceof ProcessOutput) { + if (e.stdout) console.log(e.stdout); + if (e.stderr) console.error(e.stderr); + process.exit(e.exitCode); + } else { + console.error(e); + process.exit(1); + } +}); diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 4ca0ee8a..7ee6efbf 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -19,5 +19,6 @@ add_subdirectory(lib) add_subdirectory(parser) +add_subdirectory(lsp) add_subdirectory(js) add_subdirectory(frontend) diff --git a/src/lsp/CMakeLists.txt b/src/lsp/CMakeLists.txt new file mode 100644 index 00000000..e78a41b2 --- /dev/null +++ b/src/lsp/CMakeLists.txt @@ -0,0 +1,49 @@ +# Copyright (c) 2024 Roberto Raggi +# +# Permission is hereby granted, free of charge, to any person obtaining a copy of +# this software and associated documentation files (the "Software"), to deal in +# the Software without restriction, including without limitation the rights to +# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +# the Software, and to permit persons to whom the Software is furnished to do so, +# subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +file(GLOB CXX_LSP_INCLUDE_HEADER_FILES cxx/lsp/*.h) + +aux_source_directory(cxx/lsp LSP_SOURCES) + +add_library(cxx-lsp + ${LSP_SOURCES} + ${CXX_LSP_INCLUDE_HEADER_FILES} +) + +target_include_directories(cxx-lsp + PUBLIC $ + $ +) + +target_compile_features(cxx-lsp PUBLIC cxx_std_20) + +# disable exception when targeting emscripten +if (EMSCRIPTEN) + target_compile_options(cxx-lsp PUBLIC -fno-exceptions) +endif() + +install( + FILES ${CXX_LSP_INCLUDE_HEADER_FILES} + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/cxx/lsp +) + +install( + TARGETS cxx-lsp + EXPORT cxxTargets +) diff --git a/src/lsp/cxx/lsp/enums.cc b/src/lsp/cxx/lsp/enums.cc new file mode 100644 index 00000000..fccde0e8 --- /dev/null +++ b/src/lsp/cxx/lsp/enums.cc @@ -0,0 +1,703 @@ +#include + +namespace cxx::lsp { + +auto to_string(SemanticTokenTypes value) -> std::string { + switch (value) { + case SemanticTokenTypes::kNamespace: + return "namespace"; + case SemanticTokenTypes::kType: + return "type"; + case SemanticTokenTypes::kClass: + return "class"; + case SemanticTokenTypes::kEnum: + return "enum"; + case SemanticTokenTypes::kInterface: + return "interface"; + case SemanticTokenTypes::kStruct: + return "struct"; + case SemanticTokenTypes::kTypeParameter: + return "typeParameter"; + case SemanticTokenTypes::kParameter: + return "parameter"; + case SemanticTokenTypes::kVariable: + return "variable"; + case SemanticTokenTypes::kProperty: + return "property"; + case SemanticTokenTypes::kEnumMember: + return "enumMember"; + case SemanticTokenTypes::kEvent: + return "event"; + case SemanticTokenTypes::kFunction: + return "function"; + case SemanticTokenTypes::kMethod: + return "method"; + case SemanticTokenTypes::kMacro: + return "macro"; + case SemanticTokenTypes::kKeyword: + return "keyword"; + case SemanticTokenTypes::kModifier: + return "modifier"; + case SemanticTokenTypes::kComment: + return "comment"; + case SemanticTokenTypes::kString: + return "string"; + case SemanticTokenTypes::kNumber: + return "number"; + case SemanticTokenTypes::kRegexp: + return "regexp"; + case SemanticTokenTypes::kOperator: + return "operator"; + case SemanticTokenTypes::kDecorator: + return "decorator"; + case SemanticTokenTypes::kLabel: + return "label"; + } +} + +auto to_string(SemanticTokenModifiers value) -> std::string { + switch (value) { + case SemanticTokenModifiers::kDeclaration: + return "declaration"; + case SemanticTokenModifiers::kDefinition: + return "definition"; + case SemanticTokenModifiers::kReadonly: + return "readonly"; + case SemanticTokenModifiers::kStatic: + return "static"; + case SemanticTokenModifiers::kDeprecated: + return "deprecated"; + case SemanticTokenModifiers::kAbstract: + return "abstract"; + case SemanticTokenModifiers::kAsync: + return "async"; + case SemanticTokenModifiers::kModification: + return "modification"; + case SemanticTokenModifiers::kDocumentation: + return "documentation"; + case SemanticTokenModifiers::kDefaultLibrary: + return "defaultLibrary"; + } +} + +auto to_string(DocumentDiagnosticReportKind value) -> std::string { + switch (value) { + case DocumentDiagnosticReportKind::kFull: + return "full"; + case DocumentDiagnosticReportKind::kUnchanged: + return "unchanged"; + } +} + +auto to_string(ErrorCodes value) -> std::string { + switch (value) { + case ErrorCodes::kParseError: + return "ParseError"; + case ErrorCodes::kInvalidRequest: + return "InvalidRequest"; + case ErrorCodes::kMethodNotFound: + return "MethodNotFound"; + case ErrorCodes::kInvalidParams: + return "InvalidParams"; + case ErrorCodes::kInternalError: + return "InternalError"; + case ErrorCodes::kServerNotInitialized: + return "ServerNotInitialized"; + case ErrorCodes::kUnknownErrorCode: + return "UnknownErrorCode"; + } +} + +auto to_string(LSPErrorCodes value) -> std::string { + switch (value) { + case LSPErrorCodes::kRequestFailed: + return "RequestFailed"; + case LSPErrorCodes::kServerCancelled: + return "ServerCancelled"; + case LSPErrorCodes::kContentModified: + return "ContentModified"; + case LSPErrorCodes::kRequestCancelled: + return "RequestCancelled"; + } +} + +auto to_string(FoldingRangeKind value) -> std::string { + switch (value) { + case FoldingRangeKind::kComment: + return "comment"; + case FoldingRangeKind::kImports: + return "imports"; + case FoldingRangeKind::kRegion: + return "region"; + } +} + +auto to_string(SymbolKind value) -> std::string { + switch (value) { + case SymbolKind::kFile: + return "File"; + case SymbolKind::kModule: + return "Module"; + case SymbolKind::kNamespace: + return "Namespace"; + case SymbolKind::kPackage: + return "Package"; + case SymbolKind::kClass: + return "Class"; + case SymbolKind::kMethod: + return "Method"; + case SymbolKind::kProperty: + return "Property"; + case SymbolKind::kField: + return "Field"; + case SymbolKind::kConstructor: + return "Constructor"; + case SymbolKind::kEnum: + return "Enum"; + case SymbolKind::kInterface: + return "Interface"; + case SymbolKind::kFunction: + return "Function"; + case SymbolKind::kVariable: + return "Variable"; + case SymbolKind::kConstant: + return "Constant"; + case SymbolKind::kString: + return "String"; + case SymbolKind::kNumber: + return "Number"; + case SymbolKind::kBoolean: + return "Boolean"; + case SymbolKind::kArray: + return "Array"; + case SymbolKind::kObject: + return "Object"; + case SymbolKind::kKey: + return "Key"; + case SymbolKind::kNull: + return "Null"; + case SymbolKind::kEnumMember: + return "EnumMember"; + case SymbolKind::kStruct: + return "Struct"; + case SymbolKind::kEvent: + return "Event"; + case SymbolKind::kOperator: + return "Operator"; + case SymbolKind::kTypeParameter: + return "TypeParameter"; + } +} + +auto to_string(SymbolTag value) -> std::string { + switch (value) { + case SymbolTag::kDeprecated: + return "Deprecated"; + } +} + +auto to_string(UniquenessLevel value) -> std::string { + switch (value) { + case UniquenessLevel::kDocument: + return "document"; + case UniquenessLevel::kProject: + return "project"; + case UniquenessLevel::kGroup: + return "group"; + case UniquenessLevel::kScheme: + return "scheme"; + case UniquenessLevel::kGlobal: + return "global"; + } +} + +auto to_string(MonikerKind value) -> std::string { + switch (value) { + case MonikerKind::kImport: + return "import"; + case MonikerKind::kExport: + return "export"; + case MonikerKind::kLocal: + return "local"; + } +} + +auto to_string(InlayHintKind value) -> std::string { + switch (value) { + case InlayHintKind::kType: + return "Type"; + case InlayHintKind::kParameter: + return "Parameter"; + } +} + +auto to_string(MessageType value) -> std::string { + switch (value) { + case MessageType::kError: + return "Error"; + case MessageType::kWarning: + return "Warning"; + case MessageType::kInfo: + return "Info"; + case MessageType::kLog: + return "Log"; + case MessageType::kDebug: + return "Debug"; + } +} + +auto to_string(TextDocumentSyncKind value) -> std::string { + switch (value) { + case TextDocumentSyncKind::kNone: + return "None"; + case TextDocumentSyncKind::kFull: + return "Full"; + case TextDocumentSyncKind::kIncremental: + return "Incremental"; + } +} + +auto to_string(TextDocumentSaveReason value) -> std::string { + switch (value) { + case TextDocumentSaveReason::kManual: + return "Manual"; + case TextDocumentSaveReason::kAfterDelay: + return "AfterDelay"; + case TextDocumentSaveReason::kFocusOut: + return "FocusOut"; + } +} + +auto to_string(CompletionItemKind value) -> std::string { + switch (value) { + case CompletionItemKind::kText: + return "Text"; + case CompletionItemKind::kMethod: + return "Method"; + case CompletionItemKind::kFunction: + return "Function"; + case CompletionItemKind::kConstructor: + return "Constructor"; + case CompletionItemKind::kField: + return "Field"; + case CompletionItemKind::kVariable: + return "Variable"; + case CompletionItemKind::kClass: + return "Class"; + case CompletionItemKind::kInterface: + return "Interface"; + case CompletionItemKind::kModule: + return "Module"; + case CompletionItemKind::kProperty: + return "Property"; + case CompletionItemKind::kUnit: + return "Unit"; + case CompletionItemKind::kValue: + return "Value"; + case CompletionItemKind::kEnum: + return "Enum"; + case CompletionItemKind::kKeyword: + return "Keyword"; + case CompletionItemKind::kSnippet: + return "Snippet"; + case CompletionItemKind::kColor: + return "Color"; + case CompletionItemKind::kFile: + return "File"; + case CompletionItemKind::kReference: + return "Reference"; + case CompletionItemKind::kFolder: + return "Folder"; + case CompletionItemKind::kEnumMember: + return "EnumMember"; + case CompletionItemKind::kConstant: + return "Constant"; + case CompletionItemKind::kStruct: + return "Struct"; + case CompletionItemKind::kEvent: + return "Event"; + case CompletionItemKind::kOperator: + return "Operator"; + case CompletionItemKind::kTypeParameter: + return "TypeParameter"; + } +} + +auto to_string(CompletionItemTag value) -> std::string { + switch (value) { + case CompletionItemTag::kDeprecated: + return "Deprecated"; + } +} + +auto to_string(InsertTextFormat value) -> std::string { + switch (value) { + case InsertTextFormat::kPlainText: + return "PlainText"; + case InsertTextFormat::kSnippet: + return "Snippet"; + } +} + +auto to_string(InsertTextMode value) -> std::string { + switch (value) { + case InsertTextMode::kAsIs: + return "asIs"; + case InsertTextMode::kAdjustIndentation: + return "adjustIndentation"; + } +} + +auto to_string(DocumentHighlightKind value) -> std::string { + switch (value) { + case DocumentHighlightKind::kText: + return "Text"; + case DocumentHighlightKind::kRead: + return "Read"; + case DocumentHighlightKind::kWrite: + return "Write"; + } +} + +auto to_string(CodeActionKind value) -> std::string { + switch (value) { + case CodeActionKind::kEmpty: + return ""; + case CodeActionKind::kQuickFix: + return "quickfix"; + case CodeActionKind::kRefactor: + return "refactor"; + case CodeActionKind::kRefactorExtract: + return "refactor.extract"; + case CodeActionKind::kRefactorInline: + return "refactor.inline"; + case CodeActionKind::kRefactorMove: + return "refactor.move"; + case CodeActionKind::kRefactorRewrite: + return "refactor.rewrite"; + case CodeActionKind::kSource: + return "source"; + case CodeActionKind::kSourceOrganizeImports: + return "source.organizeImports"; + case CodeActionKind::kSourceFixAll: + return "source.fixAll"; + case CodeActionKind::kNotebook: + return "notebook"; + } +} + +auto to_string(CodeActionTag value) -> std::string { + switch (value) { + case CodeActionTag::kLLMGenerated: + return "LLMGenerated"; + } +} + +auto to_string(TraceValue value) -> std::string { + switch (value) { + case TraceValue::kOff: + return "off"; + case TraceValue::kMessages: + return "messages"; + case TraceValue::kVerbose: + return "verbose"; + } +} + +auto to_string(MarkupKind value) -> std::string { + switch (value) { + case MarkupKind::kPlainText: + return "plaintext"; + case MarkupKind::kMarkdown: + return "markdown"; + } +} + +auto to_string(LanguageKind value) -> std::string { + switch (value) { + case LanguageKind::kABAP: + return "abap"; + case LanguageKind::kWindowsBat: + return "bat"; + case LanguageKind::kBibTeX: + return "bibtex"; + case LanguageKind::kClojure: + return "clojure"; + case LanguageKind::kCoffeescript: + return "coffeescript"; + case LanguageKind::kC: + return "c"; + case LanguageKind::kCPP: + return "cpp"; + case LanguageKind::kCSharp: + return "csharp"; + case LanguageKind::kCSS: + return "css"; + case LanguageKind::kD: + return "d"; + case LanguageKind::kDelphi: + return "pascal"; + case LanguageKind::kDiff: + return "diff"; + case LanguageKind::kDart: + return "dart"; + case LanguageKind::kDockerfile: + return "dockerfile"; + case LanguageKind::kElixir: + return "elixir"; + case LanguageKind::kErlang: + return "erlang"; + case LanguageKind::kFSharp: + return "fsharp"; + case LanguageKind::kGitCommit: + return "git-commit"; + case LanguageKind::kGitRebase: + return "rebase"; + case LanguageKind::kGo: + return "go"; + case LanguageKind::kGroovy: + return "groovy"; + case LanguageKind::kHandlebars: + return "handlebars"; + case LanguageKind::kHaskell: + return "haskell"; + case LanguageKind::kHTML: + return "html"; + case LanguageKind::kIni: + return "ini"; + case LanguageKind::kJava: + return "java"; + case LanguageKind::kJavaScript: + return "javascript"; + case LanguageKind::kJavaScriptReact: + return "javascriptreact"; + case LanguageKind::kJSON: + return "json"; + case LanguageKind::kLaTeX: + return "latex"; + case LanguageKind::kLess: + return "less"; + case LanguageKind::kLua: + return "lua"; + case LanguageKind::kMakefile: + return "makefile"; + case LanguageKind::kMarkdown: + return "markdown"; + case LanguageKind::kObjectiveC: + return "objective-c"; + case LanguageKind::kObjectiveCPP: + return "objective-cpp"; + case LanguageKind::kPascal: + return "pascal"; + case LanguageKind::kPerl: + return "perl"; + case LanguageKind::kPerl6: + return "perl6"; + case LanguageKind::kPHP: + return "php"; + case LanguageKind::kPowershell: + return "powershell"; + case LanguageKind::kPug: + return "jade"; + case LanguageKind::kPython: + return "python"; + case LanguageKind::kR: + return "r"; + case LanguageKind::kRazor: + return "razor"; + case LanguageKind::kRuby: + return "ruby"; + case LanguageKind::kRust: + return "rust"; + case LanguageKind::kSCSS: + return "scss"; + case LanguageKind::kSASS: + return "sass"; + case LanguageKind::kScala: + return "scala"; + case LanguageKind::kShaderLab: + return "shaderlab"; + case LanguageKind::kShellScript: + return "shellscript"; + case LanguageKind::kSQL: + return "sql"; + case LanguageKind::kSwift: + return "swift"; + case LanguageKind::kTypeScript: + return "typescript"; + case LanguageKind::kTypeScriptReact: + return "typescriptreact"; + case LanguageKind::kTeX: + return "tex"; + case LanguageKind::kVisualBasic: + return "vb"; + case LanguageKind::kXML: + return "xml"; + case LanguageKind::kXSL: + return "xsl"; + case LanguageKind::kYAML: + return "yaml"; + } +} + +auto to_string(InlineCompletionTriggerKind value) -> std::string { + switch (value) { + case InlineCompletionTriggerKind::kInvoked: + return "Invoked"; + case InlineCompletionTriggerKind::kAutomatic: + return "Automatic"; + } +} + +auto to_string(PositionEncodingKind value) -> std::string { + switch (value) { + case PositionEncodingKind::kUTF8: + return "utf-8"; + case PositionEncodingKind::kUTF16: + return "utf-16"; + case PositionEncodingKind::kUTF32: + return "utf-32"; + } +} + +auto to_string(FileChangeType value) -> std::string { + switch (value) { + case FileChangeType::kCreated: + return "Created"; + case FileChangeType::kChanged: + return "Changed"; + case FileChangeType::kDeleted: + return "Deleted"; + } +} + +auto to_string(WatchKind value) -> std::string { + switch (value) { + case WatchKind::kCreate: + return "Create"; + case WatchKind::kChange: + return "Change"; + case WatchKind::kDelete: + return "Delete"; + } +} + +auto to_string(DiagnosticSeverity value) -> std::string { + switch (value) { + case DiagnosticSeverity::kError: + return "Error"; + case DiagnosticSeverity::kWarning: + return "Warning"; + case DiagnosticSeverity::kInformation: + return "Information"; + case DiagnosticSeverity::kHint: + return "Hint"; + } +} + +auto to_string(DiagnosticTag value) -> std::string { + switch (value) { + case DiagnosticTag::kUnnecessary: + return "Unnecessary"; + case DiagnosticTag::kDeprecated: + return "Deprecated"; + } +} + +auto to_string(CompletionTriggerKind value) -> std::string { + switch (value) { + case CompletionTriggerKind::kInvoked: + return "Invoked"; + case CompletionTriggerKind::kTriggerCharacter: + return "TriggerCharacter"; + case CompletionTriggerKind::kTriggerForIncompleteCompletions: + return "TriggerForIncompleteCompletions"; + } +} + +auto to_string(ApplyKind value) -> std::string { + switch (value) { + case ApplyKind::kReplace: + return "Replace"; + case ApplyKind::kMerge: + return "Merge"; + } +} + +auto to_string(SignatureHelpTriggerKind value) -> std::string { + switch (value) { + case SignatureHelpTriggerKind::kInvoked: + return "Invoked"; + case SignatureHelpTriggerKind::kTriggerCharacter: + return "TriggerCharacter"; + case SignatureHelpTriggerKind::kContentChange: + return "ContentChange"; + } +} + +auto to_string(CodeActionTriggerKind value) -> std::string { + switch (value) { + case CodeActionTriggerKind::kInvoked: + return "Invoked"; + case CodeActionTriggerKind::kAutomatic: + return "Automatic"; + } +} + +auto to_string(FileOperationPatternKind value) -> std::string { + switch (value) { + case FileOperationPatternKind::kFile: + return "file"; + case FileOperationPatternKind::kFolder: + return "folder"; + } +} + +auto to_string(NotebookCellKind value) -> std::string { + switch (value) { + case NotebookCellKind::kMarkup: + return "Markup"; + case NotebookCellKind::kCode: + return "Code"; + } +} + +auto to_string(ResourceOperationKind value) -> std::string { + switch (value) { + case ResourceOperationKind::kCreate: + return "create"; + case ResourceOperationKind::kRename: + return "rename"; + case ResourceOperationKind::kDelete: + return "delete"; + } +} + +auto to_string(FailureHandlingKind value) -> std::string { + switch (value) { + case FailureHandlingKind::kAbort: + return "abort"; + case FailureHandlingKind::kTransactional: + return "transactional"; + case FailureHandlingKind::kTextOnlyTransactional: + return "textOnlyTransactional"; + case FailureHandlingKind::kUndo: + return "undo"; + } +} + +auto to_string(PrepareSupportDefaultBehavior value) -> std::string { + switch (value) { + case PrepareSupportDefaultBehavior::kIdentifier: + return "Identifier"; + } +} + +auto to_string(TokenFormat value) -> std::string { + switch (value) { + case TokenFormat::kRelative: + return "relative"; + } +} + +} // namespace cxx::lsp diff --git a/src/lsp/cxx/lsp/enums.h b/src/lsp/cxx/lsp/enums.h new file mode 100644 index 00000000..fdeba3e7 --- /dev/null +++ b/src/lsp/cxx/lsp/enums.h @@ -0,0 +1,417 @@ +#pragma once + +#include + +namespace cxx::lsp { + +enum class SemanticTokenTypes { + kNamespace, + kType, + kClass, + kEnum, + kInterface, + kStruct, + kTypeParameter, + kParameter, + kVariable, + kProperty, + kEnumMember, + kEvent, + kFunction, + kMethod, + kMacro, + kKeyword, + kModifier, + kComment, + kString, + kNumber, + kRegexp, + kOperator, + kDecorator, + kLabel, +}; + +enum class SemanticTokenModifiers { + kDeclaration, + kDefinition, + kReadonly, + kStatic, + kDeprecated, + kAbstract, + kAsync, + kModification, + kDocumentation, + kDefaultLibrary, +}; + +enum class DocumentDiagnosticReportKind { + kFull, + kUnchanged, +}; + +enum class ErrorCodes : int { + kParseError = -32700, + kInvalidRequest = -32600, + kMethodNotFound = -32601, + kInvalidParams = -32602, + kInternalError = -32603, + kServerNotInitialized = -32002, + kUnknownErrorCode = -32001, +}; + +enum class LSPErrorCodes : int { + kRequestFailed = -32803, + kServerCancelled = -32802, + kContentModified = -32801, + kRequestCancelled = -32800, +}; + +enum class FoldingRangeKind { + kComment, + kImports, + kRegion, +}; + +enum class SymbolKind : unsigned int { + kFile = 1, + kModule = 2, + kNamespace = 3, + kPackage = 4, + kClass = 5, + kMethod = 6, + kProperty = 7, + kField = 8, + kConstructor = 9, + kEnum = 10, + kInterface = 11, + kFunction = 12, + kVariable = 13, + kConstant = 14, + kString = 15, + kNumber = 16, + kBoolean = 17, + kArray = 18, + kObject = 19, + kKey = 20, + kNull = 21, + kEnumMember = 22, + kStruct = 23, + kEvent = 24, + kOperator = 25, + kTypeParameter = 26, +}; + +enum class SymbolTag : unsigned int { + kDeprecated = 1, +}; + +enum class UniquenessLevel { + kDocument, + kProject, + kGroup, + kScheme, + kGlobal, +}; + +enum class MonikerKind { + kImport, + kExport, + kLocal, +}; + +enum class InlayHintKind : unsigned int { + kType = 1, + kParameter = 2, +}; + +enum class MessageType : unsigned int { + kError = 1, + kWarning = 2, + kInfo = 3, + kLog = 4, + kDebug = 5, +}; + +enum class TextDocumentSyncKind : unsigned int { + kNone = 0, + kFull = 1, + kIncremental = 2, +}; + +enum class TextDocumentSaveReason : unsigned int { + kManual = 1, + kAfterDelay = 2, + kFocusOut = 3, +}; + +enum class CompletionItemKind : unsigned int { + kText = 1, + kMethod = 2, + kFunction = 3, + kConstructor = 4, + kField = 5, + kVariable = 6, + kClass = 7, + kInterface = 8, + kModule = 9, + kProperty = 10, + kUnit = 11, + kValue = 12, + kEnum = 13, + kKeyword = 14, + kSnippet = 15, + kColor = 16, + kFile = 17, + kReference = 18, + kFolder = 19, + kEnumMember = 20, + kConstant = 21, + kStruct = 22, + kEvent = 23, + kOperator = 24, + kTypeParameter = 25, +}; + +enum class CompletionItemTag : unsigned int { + kDeprecated = 1, +}; + +enum class InsertTextFormat : unsigned int { + kPlainText = 1, + kSnippet = 2, +}; + +enum class InsertTextMode : unsigned int { + kAsIs = 1, + kAdjustIndentation = 2, +}; + +enum class DocumentHighlightKind : unsigned int { + kText = 1, + kRead = 2, + kWrite = 3, +}; + +enum class CodeActionKind { + kEmpty, + kQuickFix, + kRefactor, + kRefactorExtract, + kRefactorInline, + kRefactorMove, + kRefactorRewrite, + kSource, + kSourceOrganizeImports, + kSourceFixAll, + kNotebook, +}; + +enum class CodeActionTag : unsigned int { + kLLMGenerated = 1, +}; + +enum class TraceValue { + kOff, + kMessages, + kVerbose, +}; + +enum class MarkupKind { + kPlainText, + kMarkdown, +}; + +enum class LanguageKind { + kABAP, + kWindowsBat, + kBibTeX, + kClojure, + kCoffeescript, + kC, + kCPP, + kCSharp, + kCSS, + kD, + kDelphi, + kDiff, + kDart, + kDockerfile, + kElixir, + kErlang, + kFSharp, + kGitCommit, + kGitRebase, + kGo, + kGroovy, + kHandlebars, + kHaskell, + kHTML, + kIni, + kJava, + kJavaScript, + kJavaScriptReact, + kJSON, + kLaTeX, + kLess, + kLua, + kMakefile, + kMarkdown, + kObjectiveC, + kObjectiveCPP, + kPascal, + kPerl, + kPerl6, + kPHP, + kPowershell, + kPug, + kPython, + kR, + kRazor, + kRuby, + kRust, + kSCSS, + kSASS, + kScala, + kShaderLab, + kShellScript, + kSQL, + kSwift, + kTypeScript, + kTypeScriptReact, + kTeX, + kVisualBasic, + kXML, + kXSL, + kYAML, +}; + +enum class InlineCompletionTriggerKind : unsigned int { + kInvoked = 1, + kAutomatic = 2, +}; + +enum class PositionEncodingKind { + kUTF8, + kUTF16, + kUTF32, +}; + +enum class FileChangeType : unsigned int { + kCreated = 1, + kChanged = 2, + kDeleted = 3, +}; + +enum class WatchKind : unsigned int { + kCreate = 1, + kChange = 2, + kDelete = 4, +}; + +enum class DiagnosticSeverity : unsigned int { + kError = 1, + kWarning = 2, + kInformation = 3, + kHint = 4, +}; + +enum class DiagnosticTag : unsigned int { + kUnnecessary = 1, + kDeprecated = 2, +}; + +enum class CompletionTriggerKind : unsigned int { + kInvoked = 1, + kTriggerCharacter = 2, + kTriggerForIncompleteCompletions = 3, +}; + +enum class ApplyKind : unsigned int { + kReplace = 1, + kMerge = 2, +}; + +enum class SignatureHelpTriggerKind : unsigned int { + kInvoked = 1, + kTriggerCharacter = 2, + kContentChange = 3, +}; + +enum class CodeActionTriggerKind : unsigned int { + kInvoked = 1, + kAutomatic = 2, +}; + +enum class FileOperationPatternKind { + kFile, + kFolder, +}; + +enum class NotebookCellKind : unsigned int { + kMarkup = 1, + kCode = 2, +}; + +enum class ResourceOperationKind { + kCreate, + kRename, + kDelete, +}; + +enum class FailureHandlingKind { + kAbort, + kTransactional, + kTextOnlyTransactional, + kUndo, +}; + +enum class PrepareSupportDefaultBehavior : unsigned int { + kIdentifier = 1, +}; + +enum class TokenFormat { + kRelative, +}; + +auto to_string(SemanticTokenTypes value) -> std::string; +auto to_string(SemanticTokenModifiers value) -> std::string; +auto to_string(DocumentDiagnosticReportKind value) -> std::string; +auto to_string(ErrorCodes value) -> std::string; +auto to_string(LSPErrorCodes value) -> std::string; +auto to_string(FoldingRangeKind value) -> std::string; +auto to_string(SymbolKind value) -> std::string; +auto to_string(SymbolTag value) -> std::string; +auto to_string(UniquenessLevel value) -> std::string; +auto to_string(MonikerKind value) -> std::string; +auto to_string(InlayHintKind value) -> std::string; +auto to_string(MessageType value) -> std::string; +auto to_string(TextDocumentSyncKind value) -> std::string; +auto to_string(TextDocumentSaveReason value) -> std::string; +auto to_string(CompletionItemKind value) -> std::string; +auto to_string(CompletionItemTag value) -> std::string; +auto to_string(InsertTextFormat value) -> std::string; +auto to_string(InsertTextMode value) -> std::string; +auto to_string(DocumentHighlightKind value) -> std::string; +auto to_string(CodeActionKind value) -> std::string; +auto to_string(CodeActionTag value) -> std::string; +auto to_string(TraceValue value) -> std::string; +auto to_string(MarkupKind value) -> std::string; +auto to_string(LanguageKind value) -> std::string; +auto to_string(InlineCompletionTriggerKind value) -> std::string; +auto to_string(PositionEncodingKind value) -> std::string; +auto to_string(FileChangeType value) -> std::string; +auto to_string(WatchKind value) -> std::string; +auto to_string(DiagnosticSeverity value) -> std::string; +auto to_string(DiagnosticTag value) -> std::string; +auto to_string(CompletionTriggerKind value) -> std::string; +auto to_string(ApplyKind value) -> std::string; +auto to_string(SignatureHelpTriggerKind value) -> std::string; +auto to_string(CodeActionTriggerKind value) -> std::string; +auto to_string(FileOperationPatternKind value) -> std::string; +auto to_string(NotebookCellKind value) -> std::string; +auto to_string(ResourceOperationKind value) -> std::string; +auto to_string(FailureHandlingKind value) -> std::string; +auto to_string(PrepareSupportDefaultBehavior value) -> std::string; +auto to_string(TokenFormat value) -> std::string; + +} // namespace cxx::lsp