diff --git a/include/Feature/CodeCompletion.h b/include/Feature/CodeCompletion.h index 9d158591..a4e31b22 100644 --- a/include/Feature/CodeCompletion.h +++ b/include/Feature/CodeCompletion.h @@ -6,7 +6,7 @@ namespace clice::proto { struct CompletionClientCapabilities {}; -enum CompletionItemKind { +enum class CompletionItemKind { Text = 1, Method = 2, Function = 3, diff --git a/include/Protocol/SemanticTokens.def b/include/Feature/SemanticTokens.def similarity index 99% rename from include/Protocol/SemanticTokens.def rename to include/Feature/SemanticTokens.def index f20e8b3a..34e6a9e0 100644 --- a/include/Protocol/SemanticTokens.def +++ b/include/Feature/SemanticTokens.def @@ -128,4 +128,4 @@ SEMANTIC_TOKEN_MODIFIER(Templated, "templated") SEMANTIC_TOKEN_MODIFIER(Dependent, "dependent") #undef SEMANTIC_TOKEN_TYPE -#undef SEMANTIC_TOKEN_MODIFIER \ No newline at end of file +#undef SEMANTIC_TOKEN_MODIFIER diff --git a/include/Feature/SemanticTokens.h b/include/Feature/SemanticTokens.h index 497a2733..73bef9d1 100644 --- a/include/Feature/SemanticTokens.h +++ b/include/Feature/SemanticTokens.h @@ -1,13 +1,61 @@ #pragma once -#include -#include +#include -namespace clice { -struct ParsedAST; -} +namespace clice::proto { + +// clang-format off +enum class SemanticTokenType : uint8_t { + #define SEMANTIC_TOKEN_TYPE(name, ...) name, + #include "SemanticTokens.def" + #undef SEMANTIC_TOKEN_TYPE + LAST_TYPE +}; + +enum class SemanticTokenModifier : uint8_t { + #define SEMANTIC_TOKEN_MODIFIER(name, ...) name, + #include "SemanticTokens.def" + #undef SEMANTIC_TOKEN_MODIFIER + LAST_MODIFIER +}; + +struct SemanticTokensLegend { + std::array(SemanticTokenType::LAST_TYPE)> tokenTypes = { + #define SEMANTIC_TOKEN_TYPE(name, value) value, + #include "SemanticTokens.def" + }; + + std::array(SemanticTokenModifier::LAST_MODIFIER)> tokenModifiers = { + #define SEMANTIC_TOKEN_MODIFIER(name, value) value, + #include "SemanticTokens.def" + }; +}; // clang-format on + +/// Server Capability. +struct SemanticTokensOptions { + /// The legend used by the server. + SemanticTokensLegend legend; + + /// Server supports providing semantic tokens for a specific range of a document. + bool range = false; + + /// Server supports providing semantic tokens for a full document. + bool full = true; +}; + +struct SemanticTokensParams { + /// The text document. + /// TextDocumentIdentifier textDocument; +}; + +struct SemanticTokens { + /// The actual tokens. + std::vector data; +}; + +} // namespace clice::proto namespace clice::feature { -proto::SemanticTokens semanticTokens(const ParsedAST& AST, llvm::StringRef filename); +// proto::SemanticTokens semanticTokens(const ParsedAST& AST, llvm::StringRef filename); } // namespace clice::feature diff --git a/include/Feature/SignatureHelp.h b/include/Feature/SignatureHelp.h index e69de29b..8f92b56f 100644 --- a/include/Feature/SignatureHelp.h +++ b/include/Feature/SignatureHelp.h @@ -0,0 +1,40 @@ +#pragma once + +#include + +namespace clice::proto { + +struct SignatureInformation { + /// The label of this signature. Will be shown in the UI. + string label; + + // FIXME: + // ... +}; + +struct SignatureHelp { + /// One or more signatures. If no signatures are available the signature help + /// request should return `null`. + std::vector signatures; +}; + +} // namespace clice::proto + +namespace clice { +class Compiler; +} + +namespace clice::config { + +struct SignatureHelpOption {}; + +} // namespace clice::config + +namespace clice::feature { + +proto::SignatureHelp signatureHelp(Compiler& compiler, + llvm::StringRef filepath, + proto::Position position, + const config::SignatureHelpOption& option); + +} diff --git a/include/Index/Index.h b/include/Index/Index.h index cb541a68..c3b185fa 100644 --- a/include/Index/Index.h +++ b/include/Index/Index.h @@ -1,7 +1,6 @@ #pragma once #include -#include // #include @@ -135,7 +134,11 @@ struct DenseMapInfo { } inline static llvm::hash_code getHashValue(const Location& location) { - return llvm::hash_combine(location.file, location.begin.line, location.begin.column, location.end.line, location.end.column); + return llvm::hash_combine(location.file, + location.begin.line, + location.begin.column, + location.end.line, + location.end.column); } inline static bool isEqual(const Location& LHS, const Location& RHS) { @@ -147,8 +150,8 @@ struct DenseMapInfo { namespace clice::index::out { -/// Because `SymbolID` and `Location` are duplicate referenced by `Relation`, `Symbol` and `Occurrence`, -/// To save space, we use offsets to index them. +/// Because `SymbolID` and `Location` are duplicate referenced by `Relation`, `Symbol` and +/// `Occurrence`, To save space, we use offsets to index them. template struct Ref { std::uint32_t offset; diff --git a/include/Index/Packer.h b/include/Index/Packer.h index 525b6581..d19cf851 100644 --- a/include/Index/Packer.h +++ b/include/Index/Packer.h @@ -2,6 +2,7 @@ #include "Index.h" #include "llvm/ADT/DenseMap.h" +#include namespace clice::index { diff --git a/include/Protocol/Basic.h b/include/Protocol/Basic.h deleted file mode 100644 index 68f67f3e..00000000 --- a/include/Protocol/Basic.h +++ /dev/null @@ -1,54 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include - -namespace clice::proto { - -/// range in [-2^31, 2^31- 1] -using integer = std::int32_t; - -/// range in [0, 2^31- 1] -using uinteger = std::uint32_t; - -using string = std::string_view; - -using DocumentUri = std::string; - -struct Position { - uinteger line; - uinteger character; - - friend std::strong_ordering operator<=> (const Position& lhs, const Position& rhs) = default; -}; - -struct Range { - Position start; - Position end; - - friend std::strong_ordering operator<=> (const Range& lhs, const Range& rhs) = default; -}; - -struct TextDocumentItem { - DocumentUri uri; - string languageId; - integer version; - string text; -}; - -struct TextDocumentIdentifier { - DocumentUri uri; -}; - -CLICE_RECORD(VersionedTextDocumentIdentifier, TextDocumentIdentifier) { - // The version number of this document. - // - // The version number of a document will increase after each change, - // including undo/redo. The number doesn't need to be consecutive. - integer version; -}; - -} // namespace clice::proto diff --git a/include/Protocol/Document.h b/include/Protocol/Document.h deleted file mode 100644 index 64d65ca3..00000000 --- a/include/Protocol/Document.h +++ /dev/null @@ -1,26 +0,0 @@ -#pragma once - -#include "Basic.h" - -namespace clice::proto { - -struct DidOpenTextDocumentParams { - /// The document that was opened. - TextDocumentItem textDocument; -}; - -struct TextDocumentContentChangeEvent { - /// The new text of the whole document. - string text; -}; - -struct DidChangeTextDocumentParams { - /// The document that did change. The version number points - /// to the version after all provided content changes have - /// been applied. - VersionedTextDocumentIdentifier textDocument; - - std::vector contentChanges; -}; - -} // namespace clice::proto diff --git a/include/Protocol/Lifecycle.h b/include/Protocol/Lifecycle.h deleted file mode 100644 index 4afe6e62..00000000 --- a/include/Protocol/Lifecycle.h +++ /dev/null @@ -1,70 +0,0 @@ -#pragma once - -#include "SemanticTokens.h" - -namespace clice::proto { - -enum class TextDocumentSyncKind { - None = 0, - Full = 1, - Incremental = 2, -}; - -struct ClientInfo { - /// The name of the client as defined by the client. - string name; - /// The client's version as defined by the client. - string version; -}; - -struct ClientCapabilities {}; - -struct Workplace { - /// The associated URI for this workspace folder. - string uri; - - /// The name of the workspace folder. Used to refer to this - /// workspace folder in the user interface. - string name; -}; - -struct InitializeParams { - /// Information about the client - ClientInfo clientInfo; - - /// The locale the client is currently showing the user interface - /// in. This must not necessarily be the locale of the operating - /// system. - /// - /// Uses IETF language tags as the value's syntax. - /// (See https://en.wikipedia.org/wiki/IETF_language_tag) - string locale; - - /// The capabilities provided by the client (editor or tool). - ClientCapabilities capabilities; - - /// The workspace folders configured in the client when the server starts. - /// This property is only available if the client supports workspace folders. - /// It can be `null` if the client supports workspace folders but none are - /// configured. - std::vector workspaceFolders; -}; - -struct ServerCapabilities { - std::string_view positionEncoding = "utf-16"; - TextDocumentSyncKind textDocumentSync = TextDocumentSyncKind::Full; - SemanticTokensOptions semanticTokensProvider; -}; - -struct InitializeResult { - ServerCapabilities capabilities; - - struct { - std::string_view name = "clice"; - std::string_view version = "0.0.1"; - } serverInfo; -}; - -struct InitializedParams {}; - -} // namespace clice::proto diff --git a/include/Protocol/Protocol.h b/include/Protocol/Protocol.h deleted file mode 100644 index 38dd3f30..00000000 --- a/include/Protocol/Protocol.h +++ /dev/null @@ -1,4 +0,0 @@ -#pragma once - -#include "Lifecycle.h" -#include "Document.h" \ No newline at end of file diff --git a/include/Protocol/SemanticTokens.h b/include/Protocol/SemanticTokens.h deleted file mode 100644 index e00030f9..00000000 --- a/include/Protocol/SemanticTokens.h +++ /dev/null @@ -1,56 +0,0 @@ -#pragma once - -#include "Basic.h" - -namespace clice::proto { - -// clang-format off -enum SemanticTokenType : uint8_t { - #define SEMANTIC_TOKEN_TYPE(name, ...) name, - #include "SemanticTokens.def" - #undef SEMANTIC_TOKEN_TYPE - LAST_TYPE -}; - -enum SemanticTokenModifier : uint8_t { - #define SEMANTIC_TOKEN_MODIFIER(name, ...) name, - #include "SemanticTokens.def" - #undef SEMANTIC_TOKEN_MODIFIER - LAST_MODIFIER -}; - -struct SemanticTokensLegend { - std::array tokenTypes = { - #define SEMANTIC_TOKEN_TYPE(name, value) value, - #include "SemanticTokens.def" - }; - - std::array tokenModifiers = { - #define SEMANTIC_TOKEN_MODIFIER(name, value) value, - #include "SemanticTokens.def" - }; -}; // clang-format on - -/// Server Capability. -struct SemanticTokensOptions { - /// The legend used by the server. - SemanticTokensLegend legend; - - /// Server supports providing semantic tokens for a specific range of a document. - bool range = false; - - /// Server supports providing semantic tokens for a full document. - bool full = true; -}; - -struct SemanticTokensParams { - /// The text document. - TextDocumentIdentifier textDocument; -}; - -struct SemanticTokens { - /// The actual tokens. - std::vector data; -}; - -} // namespace clice::proto diff --git a/include/Server/Config.h b/include/Server/Config.h index e752db90..3dcce6ad 100644 --- a/include/Server/Config.h +++ b/include/Server/Config.h @@ -1,6 +1,7 @@ #pragma once #include +#include namespace clice::config { diff --git a/include/Server/Server.h b/include/Server/Server.h index bc38dfd6..0b6777fd 100644 --- a/include/Server/Server.h +++ b/include/Server/Server.h @@ -1,8 +1,74 @@ #pragma once #include -#include #include +#include + +namespace clice::proto { + +enum class TextDocumentSyncKind { + None = 0, + Full = 1, + Incremental = 2, +}; + +struct ClientInfo { + /// The name of the client as defined by the client. + string name; + /// The client's version as defined by the client. + string version; +}; + +struct ClientCapabilities {}; + +struct Workplace { + /// The associated URI for this workspace folder. + string uri; + + /// The name of the workspace folder. Used to refer to this + /// workspace folder in the user interface. + string name; +}; + +struct InitializeParams { + /// Information about the client + ClientInfo clientInfo; + + /// The locale the client is currently showing the user interface + /// in. This must not necessarily be the locale of the operating + /// system. + /// + /// Uses IETF language tags as the value's syntax. + /// (See https://en.wikipedia.org/wiki/IETF_language_tag) + string locale; + + /// The capabilities provided by the client (editor or tool). + ClientCapabilities capabilities; + + /// The workspace folders configured in the client when the server starts. + /// This property is only available if the client supports workspace folders. + /// It can be `null` if the client supports workspace folders but none are + /// configured. + std::vector workspaceFolders; +}; + +struct ServerCapabilities { + std::string_view positionEncoding = "utf-16"; + TextDocumentSyncKind textDocumentSync = TextDocumentSyncKind::Full; + // SemanticTokensOptions semanticTokensProvider; +}; + +struct InitializeResult { + ServerCapabilities capabilities; + + struct { + std::string_view name = "clice"; + std::string_view version = "0.0.1"; + } serverInfo; +}; + +struct InitializedParams {}; +} // namespace clice::proto namespace clice { diff --git a/include/Support/SourceCode.h b/include/Support/SourceCode.h deleted file mode 100644 index 0a9c71b7..00000000 --- a/include/Support/SourceCode.h +++ /dev/null @@ -1,13 +0,0 @@ -#pragma once - -namespace clice { - -enum class Encoding { - UTF8, - UTF16, - UTF32, -}; - -std::size_t length(llvm::StringRef text, Encoding encoding); - -} // namespace clice diff --git a/src/Index/Packer.cpp b/src/Index/Packer.cpp index 231ec73d..31108104 100644 --- a/src/Index/Packer.cpp +++ b/src/Index/Packer.cpp @@ -123,7 +123,9 @@ std::vector Packer::pack(const in::Index& inIndex) { std::vector binary = {}; binary.reserve(layout.binarySize); - binary.insert(binary.end(), reinterpret_cast(&outIndex), reinterpret_cast(&outIndex + 1)); + binary.insert(binary.end(), + reinterpret_cast(&outIndex), + reinterpret_cast(&outIndex + 1)); binary.insert(binary.end(), reinterpret_cast(symbols.data()), reinterpret_cast(symbols.data() + symbols.size())); diff --git a/src/Server/Scheduler.cpp b/src/Server/Scheduler.cpp index ea947730..904276d6 100644 --- a/src/Server/Scheduler.cpp +++ b/src/Server/Scheduler.cpp @@ -1,5 +1,4 @@ #include -#include #include #include #include diff --git a/src/Support/SourceCode.cpp b/src/Support/SourceCode.cpp deleted file mode 100644 index f814f399..00000000 --- a/src/Support/SourceCode.cpp +++ /dev/null @@ -1,84 +0,0 @@ -#include - -namespace clice { - -namespace { - -// Here be dragons. LSP positions use columns measured in *UTF-16 code units*! -// Clangd uses UTF-8 and byte-offsets internally, so conversion is nontrivial. - -// Iterates over unicode codepoints in the (UTF-8) string. For each, -// invokes CB(UTF-8 length, UTF-16 length), and breaks if it returns true. -// Returns true if CB returned true, false if we hit the end of string. -// -// If the string is not valid UTF-8, we log this error and "decode" the -// text in some arbitrary way. This is pretty sad, but this tends to happen deep -// within indexing of headers where clang misdetected the encoding, and -// propagating the error all the way back up is (probably?) not be worth it. -template -static bool iterateCodepoints(llvm::StringRef u8string, const Callback& callback) { - bool LoggedInvalid = false; - // A codepoint takes two UTF-16 code unit if it's astral (outside BMP). - // Astral codepoints are encoded as 4 bytes in UTF-8, starting with 11110xxx. - for(size_t I = 0; I < u8string.size();) { - unsigned char C = static_cast(u8string[I]); - if(LLVM_LIKELY(!(C & 0x80))) { // ASCII character. - if(callback(1, 1)) - return true; - ++I; - continue; - } - // This convenient property of UTF-8 holds for all non-ASCII characters. - size_t UTF8Length = llvm::countl_one(C); - // 0xxx is ASCII, handled above. 10xxx is a trailing byte, invalid here. - // 11111xxx is not valid UTF-8 at all, maybe some ISO-8859-*. - if(LLVM_UNLIKELY(UTF8Length < 2 || UTF8Length > 4)) { - if(!LoggedInvalid) { - std::terminate(); - LoggedInvalid = true; - } - // We can't give a correct result, but avoid returning something wild. - // Pretend this is a valid ASCII byte, for lack of better options. - // (Too late to get ISO-8859-* right, we've skipped some bytes already). - if(callback(1, 1)) - return true; - ++I; - continue; - } - I += UTF8Length; // Skip over all trailing bytes. - // A codepoint takes two UTF-16 code unit if it's astral (outside BMP). - // Astral codepoints are encoded as 4 bytes in UTF-8 (11110xxx ...) - if(callback(UTF8Length, UTF8Length == 4 ? 2 : 1)) - return true; - } - return false; -} - -} // namespace - -std::size_t length(llvm::StringRef u8string, Encoding encoding) { - size_t count = 0; - switch(encoding) { - case Encoding::UTF8: { - count = u8string.size(); - break; - } - case Encoding::UTF16: { - iterateCodepoints(u8string, [&](int U8Len, int U16Len) { - count += U16Len; - return false; - }); - break; - } - case Encoding::UTF32: { - iterateCodepoints(u8string, [&](int U8Len, int U16Len) { - ++count; - return false; - }); - break; - } - } - return count; -} - -} // namespace clice