diff options
author | Norbert Preining <norbert@preining.info> | 2024-11-13 03:03:42 +0000 |
---|---|---|
committer | Norbert Preining <norbert@preining.info> | 2024-11-13 03:03:42 +0000 |
commit | 5037cc8f66c1c2dfc56accf0f29866977fce1f11 (patch) | |
tree | 916c5b917a84c268d98a6176a93f0a4c3e63a102 /graphics/asymptote/LspCpp/src/lsp | |
parent | d63a87aba38d505e5b1322a0fd3b93549e7cb203 (diff) |
CTAN sync 202411130303
Diffstat (limited to 'graphics/asymptote/LspCpp/src/lsp')
-rw-r--r-- | graphics/asymptote/LspCpp/src/lsp/Markup.cpp | 942 | ||||
-rw-r--r-- | graphics/asymptote/LspCpp/src/lsp/ParentProcessWatcher.cpp | 107 | ||||
-rw-r--r-- | graphics/asymptote/LspCpp/src/lsp/ProtocolJsonHandler.cpp | 716 | ||||
-rw-r--r-- | graphics/asymptote/LspCpp/src/lsp/initialize.cpp | 45 | ||||
-rw-r--r-- | graphics/asymptote/LspCpp/src/lsp/lsp.cpp | 1089 | ||||
-rw-r--r-- | graphics/asymptote/LspCpp/src/lsp/lsp_diagnostic.cpp | 75 | ||||
-rw-r--r-- | graphics/asymptote/LspCpp/src/lsp/textDocument.cpp | 349 | ||||
-rw-r--r-- | graphics/asymptote/LspCpp/src/lsp/utils.cpp | 612 | ||||
-rw-r--r-- | graphics/asymptote/LspCpp/src/lsp/working_files.cpp | 186 |
9 files changed, 0 insertions, 4121 deletions
diff --git a/graphics/asymptote/LspCpp/src/lsp/Markup.cpp b/graphics/asymptote/LspCpp/src/lsp/Markup.cpp deleted file mode 100644 index f22baac95d..0000000000 --- a/graphics/asymptote/LspCpp/src/lsp/Markup.cpp +++ /dev/null @@ -1,942 +0,0 @@ -//===--- Markup.cpp -----------------------------------------*- C++-*------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://lsp.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// -#include "LibLsp/lsp/Markup/Markup.h" - -#include <algorithm> -#include <cassert> -#include <cstddef> -#include <iterator> -#include <memory> -#include <string> -#include <vector> -#include <boost/algorithm/string.hpp> - -namespace lsp { - - /// hexdigit - Return the hexadecimal character for the - /// given number \p X (which should be less than 16). - inline char hexdigit(unsigned X, bool LowerCase = false) { - const char HexChar = LowerCase ? 'a' : 'A'; - return X < 10 ? '0' + X : HexChar + X - 10; - } - - /// Given an array of c-style strings terminated by a null pointer, construct - /// a vector of StringRefs representing the same strings without the terminating - /// null string. - inline std::vector< std::string_ref> toStringRefArray(const char* const* Strings) { - std::vector< std::string_ref> Result; - while (*Strings) - Result.push_back(*Strings++); - return Result; - } - - /// Construct a string ref from a boolean. - inline std::string_ref toStringRef(bool B) { return std::string_ref(B ? "true" : "false"); } - - /// Construct a string ref from an array ref of unsigned chars. - inline std::string_ref toStringRef(const std::vector<uint8_t>& Input) { - return std::string_ref(Input.begin(), Input.end()); - } - - /// Construct a string ref from an array ref of unsigned chars. - inline std::vector<uint8_t> arrayRefFromStringRef(const std::string_ref& Input) { - return { Input.begin(), Input.end() }; - } - - /// Interpret the given character \p C as a hexadecimal digit and return its - /// value. - /// - /// If \p C is not a valid hex digit, -1U is returned. - inline unsigned hexDigitValue(char C) { - struct HexTable { - unsigned LUT[255] = {}; - constexpr HexTable() { - // Default initialize everything to invalid. - for (int i = 0; i < 255; ++i) - LUT[i] = ~0U; - // Initialize `0`-`9`. - for (int i = 0; i < 10; ++i) - LUT['0' + i] = i; - // Initialize `A`-`F` and `a`-`f`. - for (int i = 0; i < 6; ++i) - LUT['A' + i] = LUT['a' + i] = 10 + i; - } - }; - constexpr HexTable Table; - return Table.LUT[static_cast<unsigned char>(C)]; - } - - /// Checks if character \p C is one of the 10 decimal digits. - inline bool isDigit(char C) { return C >= '0' && C <= '9'; } - - /// Checks if character \p C is a hexadecimal numeric character. - inline bool isHexDigit(char C) { return hexDigitValue(C) != ~0U; } - - /// Checks if character \p C is a valid letter as classified by "C" locale. - inline bool isAlpha(char C) { - return ('a' <= C && C <= 'z') || ('A' <= C && C <= 'Z'); - } - - /// Checks whether character \p C is either a decimal digit or an uppercase or - /// lowercase letter as classified by "C" locale. - inline bool isAlnum(char C) { return isAlpha(C) || isDigit(C); } - - /// Checks whether character \p C is valid ASCII (high bit is zero). - inline bool isASCII(char C) { return static_cast<unsigned char>(C) <= 127; } - - /// Checks whether all characters in S are ASCII. - inline bool isASCII(std::string_ref S) { - for (char C : S) - { - if(!isASCII(C))return true; - } - return true; - } - - /// Checks whether character \p C is printable. - /// - /// Locale-independent version of the C standard library isprint whose results - /// may differ on different platforms. - inline bool isPrint(char C) { - unsigned char UC = static_cast<unsigned char>(C); - return (0x20 <= UC) && (UC <= 0x7E); - } - - /// Checks whether character \p C is whitespace in the "C" locale. - /// - /// Locale-independent version of the C standard library isspace. - inline bool isSpace(char C) { - return C == ' ' || C == '\f' || C == '\n' || C == '\r' || C == '\t' || - C == '\v'; - } - - /// Returns the corresponding lowercase character if \p x is uppercase. - inline char toLower(char x) { - if (x >= 'A' && x <= 'Z') - return x - 'A' + 'a'; - return x; - } - - /// Returns the corresponding uppercase character if \p x is lowercase. - inline char toUpper(char x) { - if (x >= 'a' && x <= 'z') - return x - 'a' + 'A'; - return x; - } - - inline std::string utohexstr(uint64_t X, bool LowerCase = false) { - char Buffer[17]; - char* BufPtr = std::end(Buffer); - - if (X == 0) *--BufPtr = '0'; - - while (X) { - unsigned char Mod = static_cast<unsigned char>(X) & 15; - *--BufPtr = hexdigit(Mod, LowerCase); - X >>= 4; - } - - return std::string(BufPtr, std::end(Buffer)); - } - - /// Convert buffer \p Input to its hexadecimal representation. - /// The returned string is double the size of \p Input. - inline std::string toHex( std::string_ref Input, bool LowerCase = false) { - static const char* const LUT = "0123456789ABCDEF"; - const uint8_t Offset = LowerCase ? 32 : 0; - size_t Length = Input.size(); - - std::string Output; - Output.reserve(2 * Length); - for (size_t i = 0; i < Length; ++i) { - const unsigned char c = Input[i]; - Output.push_back(LUT[c >> 4] | Offset); - Output.push_back(LUT[c & 15] | Offset); - } - return Output; - } - - inline std::string toHex(std::vector<uint8_t> Input, bool LowerCase = false) { - return toHex(toStringRef(Input), LowerCase); - } - - /// Store the binary representation of the two provided values, \p MSB and - /// \p LSB, that make up the nibbles of a hexadecimal digit. If \p MSB or \p LSB - /// do not correspond to proper nibbles of a hexadecimal digit, this method - /// returns false. Otherwise, returns true. - inline bool tryGetHexFromNibbles(char MSB, char LSB, uint8_t& Hex) { - unsigned U1 = hexDigitValue(MSB); - unsigned U2 = hexDigitValue(LSB); - if (U1 == ~0U || U2 == ~0U) - return false; - - Hex = static_cast<uint8_t>((U1 << 4) | U2); - return true; - } - - /// Return the binary representation of the two provided values, \p MSB and - /// \p LSB, that make up the nibbles of a hexadecimal digit. - inline uint8_t hexFromNibbles(char MSB, char LSB) { - uint8_t Hex = 0; - bool GotHex = tryGetHexFromNibbles(MSB, LSB, Hex); - (void)GotHex; - assert(GotHex && "MSB and/or LSB do not correspond to hex digits"); - return Hex; - } - - /// Convert hexadecimal string \p Input to its binary representation and store - /// the result in \p Output. Returns true if the binary representation could be - /// converted from the hexadecimal string. Returns false if \p Input contains - /// non-hexadecimal digits. The output string is half the size of \p Input. - inline bool tryGetFromHex( std::string_ref Input, std::string& Output) { - if (Input.empty()) - return true; - - Output.reserve((Input.size() + 1) / 2); - if (Input.size() % 2 == 1) { - uint8_t Hex = 0; - if (!tryGetHexFromNibbles('0', Input.front(), Hex)) - return false; - - Output.push_back(Hex); - Input = Input.drop_front(); - } - - assert(Input.size() % 2 == 0); - while (!Input.empty()) { - uint8_t Hex = 0; - if (!tryGetHexFromNibbles(Input[0], Input[1], Hex)) - return false; - - Output.push_back(Hex); - Input = Input.drop_front(2); - } - return true; - } - - /// Convert hexadecimal string \p Input to its binary representation. - /// The return string is half the size of \p Input. - inline std::string fromHex( std::string_ref Input) { - std::string Hex; - bool GotHex = tryGetFromHex(Input, Hex); - (void)GotHex; - assert(GotHex && "Input contains non hex digits"); - return Hex; - } - - - - inline std::string utostr(uint64_t X, bool isNeg = false) { - char Buffer[21]; - char* BufPtr = std::end(Buffer); - - if (X == 0) *--BufPtr = '0'; // Handle special case... - - while (X) { - *--BufPtr = '0' + char(X % 10); - X /= 10; - } - - if (isNeg) *--BufPtr = '-'; // Add negative sign... - return std::string(BufPtr, std::end(Buffer)); - } - - inline std::string itostr(int64_t X) { - if (X < 0) - return utostr(static_cast<uint64_t>(1) + ~static_cast<uint64_t>(X), true); - else - return utostr(static_cast<uint64_t>(X)); - } - - /// StrInStrNoCase - Portable version of strcasestr. Locates the first - /// occurrence of string 's1' in string 's2', ignoring case. Returns - /// the offset of s2 in s1 or npos if s2 cannot be found. - std::string_ref::size_type StrInStrNoCase( std::string_ref s1, std::string_ref s2); - - /// getToken - This function extracts one token from source, ignoring any - /// leading characters that appear in the Delimiters string, and ending the - /// token at any of the characters that appear in the Delimiters string. If - /// there are no tokens in the source string, an empty string is returned. - /// The function returns a pair containing the extracted token and the - /// remaining tail string. - std::pair< std::string_ref, std::string_ref> getToken( std::string_ref Source, - std::string_ref Delimiters = " \t\n\v\f\r"); - - - - /// Returns the English suffix for an ordinal integer (-st, -nd, -rd, -th). - inline std::string_ref getOrdinalSuffix(unsigned Val) { - // It is critically important that we do this perfectly for - // user-written sequences with over 100 elements. - switch (Val % 100) { - case 11: - case 12: - case 13: - return "th"; - default: - switch (Val % 10) { - case 1: return "st"; - case 2: return "nd"; - case 3: return "rd"; - default: return "th"; - } - } - } - - namespace detail { - - template <typename IteratorT> - inline std::string join_impl(IteratorT Begin, IteratorT End, - std::string_ref Separator, std::input_iterator_tag) { - std::string S; - if (Begin == End) - return S; - - S += (*Begin); - while (++Begin != End) { - S += Separator; - S += (*Begin); - } - return S; - } - - template <typename IteratorT> - inline std::string join_impl(IteratorT Begin, IteratorT End, - std::string_ref Separator, std::forward_iterator_tag) { - std::string S; - if (Begin == End) - return S; - - size_t Len = (std::distance(Begin, End) - 1) * Separator.size(); - for (IteratorT I = Begin; I != End; ++I) - Len += (*I).size(); - S.reserve(Len); - size_t PrevCapacity = S.capacity(); - (void)PrevCapacity; - S += (*Begin); - while (++Begin != End) { - S += Separator; - S += (*Begin); - } - assert(PrevCapacity == S.capacity() && "String grew during building"); - return S; - } - - template <typename Sep> - inline void join_items_impl(std::string& Result, Sep Separator) {} - - template <typename Sep, typename Arg> - inline void join_items_impl(std::string& Result, Sep Separator, - const Arg& Item) { - Result += Item; - } - - template <typename Sep, typename Arg1, typename... Args> - inline void join_items_impl(std::string& Result, Sep Separator, const Arg1& A1, - Args &&... Items) { - Result += A1; - Result += Separator; - join_items_impl(Result, Separator, std::forward<Args>(Items)...); - } - - inline size_t join_one_item_size(char) { return 1; } - inline size_t join_one_item_size(const char* S) { return S ? ::strlen(S) : 0; } - - template <typename T> inline size_t join_one_item_size(const T& Str) { - return Str.size(); - } - - inline size_t join_items_size() { return 0; } - - template <typename A1> inline size_t join_items_size(const A1& A) { - return join_one_item_size(A); - } - template <typename A1, typename... Args> - inline size_t join_items_size(const A1& A, Args &&... Items) { - return join_one_item_size(A) + join_items_size(std::forward<Args>(Items)...); - } - - } // end namespace detail - - /// Joins the strings in the range [Begin, End), adding Separator between - /// the elements. - template <typename IteratorT> - inline std::string join(IteratorT Begin, IteratorT End, std::string_ref Separator) { - using tag = typename std::iterator_traits<IteratorT>::iterator_category; - return detail::join_impl(Begin, End, Separator, tag()); - } - - /// Joins the strings in the range [R.begin(), R.end()), adding Separator - /// between the elements. - template <typename Range> - inline std::string join(Range&& R, std::string_ref Separator) { - return join(R.begin(), R.end(), Separator); - } - - /// Joins the strings in the parameter pack \p Items, adding \p Separator - /// between the elements. All arguments must be implicitly convertible to - /// std::string, or there should be an overload of std::string::operator+=() - /// that accepts the argument explicitly. - template <typename Sep, typename... Args> - inline std::string join_items(Sep Separator, Args &&... Items) { - std::string Result; - if (sizeof...(Items) == 0) - return Result; - - size_t NS = detail::join_one_item_size(Separator); - size_t NI = detail::join_items_size(std::forward<Args>(Items)...); - Result.reserve(NI + (sizeof...(Items) - 1) * NS + 1); - detail::join_items_impl(Result, Separator, std::forward<Args>(Items)...); - return Result; - } - - /// A helper class to return the specified delimiter string after the first - /// invocation of operator std::string_ref(). Used to generate a comma-separated - /// list from a loop like so: - /// - /// \code - /// ListSeparator LS; - /// for (auto &I : C) - /// OS << LS << I.getName(); - /// \end - class ListSeparator { - bool First = true; - std::string_ref Separator; - - public: - ListSeparator( std::string_ref Separator = ", ") : Separator(Separator) {} - operator std::string_ref() { - if (First) { - First = false; - return {}; - } - return Separator; - } - }; - -} // end namespace lsp - -namespace lsp{ - -// Is <contents a plausible start to an HTML tag? -// Contents may not be the rest of the line, but it's the rest of the plain -// text, so we expect to see at least the tag name. -bool looksLikeTag(std::string_ref& Contents) { - if (Contents.empty()) - return false; - if (Contents.front() == '!' || Contents.front() == '?' || - Contents.front() == '/') - return true; - // Check the start of the tag name. - if (!lsp::isAlpha(Contents.front())) - return false; - // Drop rest of the tag name, and following whitespace. - Contents = Contents - .drop_while([](char C) { - return lsp::isAlnum(C) || C == '-' || C == '_' || C == ':'; - }) - .drop_while(lsp::isSpace); - // The rest of the tag consists of attributes, which have restrictive names. - // If we hit '=', all bets are off (attribute values can contain anything). - for (; !Contents.empty(); Contents = Contents.drop_front()) { - if (lsp::isAlnum(Contents.front()) || lsp::isSpace(Contents.front())) - continue; - if (Contents.front() == '>' || Contents.start_with("/>")) - return true; // May close the tag. - if (Contents.front() == '=') - return true; // Don't try to parse attribute values. - return false; // Random punctuation means this isn't a tag. - } - return true; // Potentially incomplete tag. -} - -// Tests whether C should be backslash-escaped in markdown. -// The string being escaped is Before + C + After. This is part of a paragraph. -// StartsLine indicates whether `Before` is the start of the line. -// After may not be everything until the end of the line. -// -// It's always safe to escape punctuation, but want minimal escaping. -// The strategy is to escape the first character of anything that might start -// a markdown grammar construct. -bool needsLeadingEscape(char C, std::string_ref Before, std::string_ref After, - bool StartsLine) { - - auto RulerLength = [&]() -> /*Length*/ unsigned { - if (!StartsLine || !Before.empty()) - return false; - std::string_ref A = After.trim_right(); - return std::all_of(A.begin(),A.end(), [C](char D) { return C == D; }) ? 1 + A.size() : 0; - }; - auto IsBullet = [&]() { - return StartsLine && Before.empty() && - (After.empty() || After.start_with(" ")); - }; - auto SpaceSurrounds = [&]() { - return (After.empty() || std::isspace(After.front())) && - (Before.empty() || std::isspace(Before.back())); - }; - - auto WordSurrounds = [&]() { - return (!After.empty() && std::isalnum(After.front())) && - (!Before.empty() && std::isalnum(Before.back())); - }; - - switch (C) { - case '\\': // Escaped character. - return true; - case '`': // Code block or inline code - // Any number of backticks can delimit an inline code block that can end - // anywhere (including on another line). We must escape them all. - return true; - case '~': // Code block - return StartsLine && Before.empty() && After.start_with("~~"); - case '#': { // ATX heading. - if (!StartsLine || !Before.empty()) - return false; - std::string_ref& Rest = After.trim_left(C); - return Rest.empty() || Rest.start_with(" "); - } - case ']': // Link or link reference. - // We escape ] rather than [ here, because it's more constrained: - // ](...) is an in-line link - // ]: is a link reference - // The following are only links if the link reference exists: - // ] by itself is a shortcut link - // ][...] is an out-of-line link - // Because we never emit link references, we don't need to handle these. - return After.start_with(":") || After.start_with("("); - case '=': // Setex heading. - return RulerLength() > 0; - case '_': // Horizontal ruler or matched delimiter. - if (RulerLength() >= 3) - return true; - // Not a delimiter if surrounded by space, or inside a word. - // (The rules at word boundaries are subtle). - return !(SpaceSurrounds() || WordSurrounds()); - case '-': // Setex heading, horizontal ruler, or bullet. - if (RulerLength() > 0) - return true; - return IsBullet(); - case '+': // Bullet list. - return IsBullet(); - case '*': // Bullet list, horizontal ruler, or delimiter. - return IsBullet() || RulerLength() >= 3 || !SpaceSurrounds(); - case '<': // HTML tag (or autolink, which we choose not to escape) - return looksLikeTag(After); - case '>': // Quote marker. Needs escaping at start of line. - return StartsLine && Before.empty(); - case '&': { // HTML entity reference - auto End = After.find(';'); - if (End == std::string_ref::npos) - return false; - std::string_ref Content = After.substr(0, End); - if (Content.consume_front("#")) - { - if (Content.consume_front("x") || Content.consume_front("X")) - { - return std::all_of(Content.begin(),Content.end(), lsp::isHexDigit); - } - - return std::all_of(Content.begin(), Content.end(), [](char c) - { - return lsp::isDigit(c); - }); - } - return std::all_of(Content.begin(), Content.end(), [](char c) - { - return lsp::isAlpha(c); - }); - } - case '.': // Numbered list indicator. Escape 12. -> 12\. at start of line. - case ')': - return StartsLine && !Before.empty() && - std::all_of(Before.begin(), Before.end(), [](char c) - { - return lsp::isDigit(c); - }) && After.start_with(" "); - default: - return false; - } -} - -/// Escape a markdown text block. Ensures the punctuation will not introduce -/// any of the markdown constructs. - std::string_ref renderText(const std::string_ref& Input, bool StartsLine) { - std::string_ref R; - for (unsigned I = 0; I < Input.size(); ++I) { - if (needsLeadingEscape(Input[I], Input.substr(0, I), Input.substr(I + 1), - StartsLine)) - R.push_back('\\'); - R.push_back(Input[I]); - } - return R; -} - -/// Renders \p Input as an inline block of code in markdown. The returned value -/// is surrounded by backticks and the inner contents are properly escaped. - std::string_ref renderInlineBlock(const std::string_ref& Input) { - std::string_ref R; - // Double all backticks to make sure we don't close the inline block early. - for (size_t From = 0; From < Input.size();) { - size_t Next = Input.find("`", From); - R += Input.substr(From, Next - From); - if (Next == std::string_ref::npos) - break; - R += "``"; // double the found backtick. - - From = Next + 1; - } - // If results starts with a backtick, add spaces on both sides. The spaces - // are ignored by markdown renderers. - if (std::string_ref(R).start_with("`") || std::string_ref(R).end_with("`")) - return "` " + std::move(R) + " `"; - // Markdown render should ignore first and last space if both are there. We - // add an extra pair of spaces in that case to make sure we render what the - // user intended. - if (std::string_ref(R).start_with(" ") && std::string_ref(R).end_with(" ")) - return "` " + std::move(R) + " `"; - return "`" + std::move(R) + "`"; -} - -/// Get marker required for \p Input to represent a markdown codeblock. It -/// consists of at least 3 backticks(`). Although markdown also allows to use -/// tilde(~) for code blocks, they are never used. - std::string_ref getMarkerForCodeBlock(const std::string_ref& Input) { - // Count the maximum number of consecutive backticks in \p Input. We need to - // start and end the code block with more. - unsigned MaxBackticks = 0; - unsigned Backticks = 0; - for (char C : Input) { - if (C == '`') { - ++Backticks; - continue; - } - MaxBackticks = std::max(MaxBackticks, Backticks); - Backticks = 0; - } - MaxBackticks = std::max(Backticks, MaxBackticks); - // Use the corresponding number of backticks to start and end a code block. - return std::string_ref(/*Repeat=*/std::max(3u, MaxBackticks + 1), '`'); -} - - /// SplitString - Split up the specified string according to the specified -/// delimiters, appending the result fragments to the output list. - void SplitString(const std::string& Source, - std::vector<std::string_ref>& OutFragments, - std::string Delimiters = " \t\n\v\f\r") -{ - boost::split(OutFragments, Source, boost::is_any_of(Delimiters)); -} - - -// Trims the input and concatenates whitespace blocks into a single ` `. - std::string_ref canonicalizeSpaces(const std::string_ref& Input) { - std::vector<std::string_ref> Words; - SplitString(Input, Words); - - return lsp::join(Words, " "); -} - - - std::string_ref renderBlocks( std::vector<Block*>&& Children, - void (Block::* RenderFunc)(std::ostringstream&) const) { - std::string_ref R; - std::ostringstream OS(R); - - std::vector<int> v{ 1, 2, 3 }; - - // Trim rulers. - Children.erase(std::remove_if(Children.begin(), Children.end(), [](const Block* C) - { - return C->isRuler(); - }), Children.end()); - - bool LastBlockWasRuler = true; - for (const auto& C : Children) { - if (C->isRuler() && LastBlockWasRuler) - continue; - LastBlockWasRuler = C->isRuler(); - ((*C).*RenderFunc)(OS); - } - - // Get rid of redundant empty lines introduced in plaintext while imitating - // padding in markdown. - std::string_ref AdjustedResult; - std::string_ref TrimmedText(OS.str()); - TrimmedText = TrimmedText.trim(); - - std::copy_if(TrimmedText.begin(), TrimmedText.end(), - std::back_inserter(AdjustedResult), - [&TrimmedText](const char& C) { - return !std::string_ref(TrimmedText.data(), - &C - TrimmedText.data() + 1) - // We allow at most two newlines. - .end_with("\n\n\n"); - }); - - return AdjustedResult; - }; - std::string_ref renderBlocks(const std::vector<std::unique_ptr<Block> >& children, - void (Block::* renderFunc)(std::ostringstream&) const) - { - std::vector<Block*> temp(children.size(), nullptr); - for(size_t i = 0 ; i < children.size() ; ++i) - { - temp[i]=(children[i].get()); - } - return renderBlocks(std::move(temp), renderFunc); - } -// Separates two blocks with extra spacing. Note that it might render strangely -// in vscode if the trailing block is a codeblock, see -// https://github.com/microsoft/vscode/issues/88416 for details. -class Ruler : public Block { -public: - void renderMarkdown(std::ostringstream &OS) const override { - // Note that we need an extra new line before the ruler, otherwise we might - // make previous block a title instead of introducing a ruler. - OS << "\n---\n"; - } - void renderPlainText(std::ostringstream &OS) const override { OS << '\n'; } - std::unique_ptr<Block> clone() const override { - return std::make_unique<Ruler>(*this); - } - bool isRuler() const override { return true; } -}; - -class CodeBlock : public Block { -public: - void renderMarkdown(std::ostringstream &OS) const override { - std::string_ref Marker = getMarkerForCodeBlock(Contents); - // No need to pad from previous blocks, as they should end with a new line. - OS << Marker << Language << '\n' << Contents << '\n' << Marker << '\n'; - } - - void renderPlainText(std::ostringstream &OS) const override { - // In plaintext we want one empty line before and after codeblocks. - OS << '\n' << Contents << "\n\n"; - } - - std::unique_ptr<Block> clone() const override { - return std::make_unique<CodeBlock>(*this); - } - - CodeBlock( std::string_ref Contents, std::string_ref Language) - : Contents(std::move(Contents)), Language(std::move(Language)) {} - -private: - - std::string_ref Contents; - std::string_ref Language; -}; - -// Inserts two spaces after each `\n` to indent each line. First line is not -// indented. - std::string_ref indentLines(const std::string_ref& Input) { - assert(!Input.end_with("\n") && "Input should've been trimmed."); - std::string_ref IndentedR; - // We'll add 2 spaces after each new line. - IndentedR.reserve(Input.size() + Input.count("\n") * 2); - for (char C : Input) { - IndentedR += C; - if (C == '\n') - IndentedR.append(" "); - } - return IndentedR; -} - -class Heading : public Paragraph { -public: - Heading(size_t Level) : Level(Level) {} - void renderMarkdown(std::ostringstream &OS) const override { - OS << std::string_ref(Level, '#') << ' '; - Paragraph::renderMarkdown(OS); - } - -private: - size_t Level; -}; - - - - - - std::string_ref Block::asMarkdown() const { - std::string_ref R; - std::ostringstream OS(R); - renderMarkdown(OS); - return std::string_ref(OS.str()).trim(); -} - - std::string_ref Block::asPlainText() const { - std::string_ref R; - std::ostringstream OS(R); - renderPlainText(OS); - return std::string_ref(OS.str()).trim().c_str(); -} - - void Paragraph::renderMarkdown(std::ostringstream& OS) const { - bool NeedsSpace = false; - bool HasChunks = false; - for (auto& C : Chunks) { - if (C.SpaceBefore || NeedsSpace) - OS << " "; - switch (C.Kind) { - case Chunk::PlainText: - OS << renderText(C.Contents, !HasChunks); - break; - case Chunk::InlineCode: - OS << renderInlineBlock(C.Contents); - break; - } - HasChunks = true; - NeedsSpace = C.SpaceAfter; - } - // Paragraphs are translated into markdown lines, not markdown paragraphs. - // Therefore it only has a single linebreak afterwards. - // VSCode requires two spaces at the end of line to start a new one. - OS << " \n"; - } - - std::unique_ptr<Block> Paragraph::clone() const { - return std::make_unique<Paragraph>(*this); - } - - /// Choose a marker to delimit `Text` from a prioritized list of options. - /// This is more readable than escaping for plain-text. - std::string_ref chooseMarker(std::vector<std::string_ref> Options, - const std::string_ref& Text) - { - // Prefer a delimiter whose characters don't appear in the text. - for (std::string_ref& S : Options) - if (Text.find_first_of(S) == std::string_ref::npos) - return S; - return Options.front(); - } - - void Paragraph::renderPlainText(std::ostringstream& OS) const { - bool NeedsSpace = false; - for (auto& C : Chunks) { - if (C.SpaceBefore || NeedsSpace) - OS << " "; - std::string_ref Marker = ""; - if (C.Preserve && C.Kind == Chunk::InlineCode) - Marker = chooseMarker({ "`", "'", "\"" }, C.Contents); - OS << Marker << C.Contents << Marker; - NeedsSpace = C.SpaceAfter; - } - OS << '\n'; - } - - void BulletList::renderMarkdown(std::ostringstream& OS) const { - for (auto& D : Items) { - // Instead of doing this we might prefer passing Indent to children to get - // rid of the copies, if it turns out to be a bottleneck. - - OS << "- "; - OS << indentLines(D.asMarkdown()) << '\n'; - } - // We need a new line after list to terminate it in markdown. - OS << '\n'; - } - - void BulletList::renderPlainText(std::ostringstream& OS) const { - for (auto& D : Items) { - // Instead of doing this we might prefer passing Indent to children to get - // rid of the copies, if it turns out to be a bottleneck. - OS << "- " << indentLines(D.asPlainText()) << '\n'; - } - } - - Paragraph& Paragraph::appendSpace() { - if (!Chunks.empty()) - Chunks.back().SpaceAfter = true; - return *this; - } - - Paragraph& Paragraph::appendText(const std::string_ref& Text) { - std::string_ref Norm = canonicalizeSpaces(Text); - if (Norm.empty()) - return *this; - Chunks.emplace_back(); - Chunk& C = Chunks.back(); - C.Contents = std::move(Norm); - C.Kind = Chunk::PlainText; - - C.SpaceBefore = std::isspace(Text.front()); - C.SpaceAfter = std::isspace(Text.back()); - return *this; - } - - Paragraph& Paragraph::appendCode(const std::string_ref& Code, bool Preserve) { - bool AdjacentCode = - !Chunks.empty() && Chunks.back().Kind == Chunk::InlineCode; - std::string_ref Norm = canonicalizeSpaces(Code); - if (Norm.empty()) - return *this; - Chunks.emplace_back(); - Chunk& C = Chunks.back(); - C.Contents = std::move(Norm); - C.Kind = Chunk::InlineCode; - C.Preserve = Preserve; - // Disallow adjacent code spans without spaces, markdown can't render them. - C.SpaceBefore = AdjacentCode; - return *this; - } - - std::unique_ptr<Block> BulletList::clone() const { - return std::make_unique<BulletList>(*this); - } - - class Document& BulletList::addItem() { - Items.emplace_back(); - return Items.back(); - } - - Document& Document::operator=(const Document& Other) { - Children.clear(); - for (const auto& C : Other.Children) - Children.push_back(C->clone()); - return *this; - } - - void Document::append(Document Other) { - std::move(Other.Children.begin(), Other.Children.end(), - std::back_inserter(Children)); - } - - Paragraph& Document::addParagraph() { - Children.push_back(std::make_unique<Paragraph>()); - return *static_cast<Paragraph*>(Children.back().get()); - } - - void Document::addRuler() { Children.push_back(std::make_unique<Ruler>()); } - - void Document::addCodeBlock(std::string_ref Code, std::string_ref Language) { - Children.emplace_back( - std::make_unique<CodeBlock>(std::move(Code), std::move(Language))); - } - - std::string_ref Document::asMarkdown() const { - return renderBlocks(Children, &Block::renderMarkdown); - } - - std::string_ref Document::asPlainText() const { - return renderBlocks(Children, &Block::renderPlainText); - } - - BulletList& Document::addBulletList() { - Children.emplace_back(std::make_unique<BulletList>()); - return *static_cast<BulletList*>(Children.back().get()); - } - - Paragraph& Document::addHeading(size_t Level) { - assert(Level > 0); - Children.emplace_back(std::make_unique<Heading>(Level)); - return *static_cast<Paragraph*>(Children.back().get()); - } - }; diff --git a/graphics/asymptote/LspCpp/src/lsp/ParentProcessWatcher.cpp b/graphics/asymptote/LspCpp/src/lsp/ParentProcessWatcher.cpp deleted file mode 100644 index c698a3157e..0000000000 --- a/graphics/asymptote/LspCpp/src/lsp/ParentProcessWatcher.cpp +++ /dev/null @@ -1,107 +0,0 @@ -#include "LibLsp/lsp/ParentProcessWatcher.h" -#include <algorithm> -#include <boost/process.hpp> - -#ifdef _WIN32 -#include <boost/process/windows.hpp> -#endif - -#include <boost/filesystem.hpp> -#include <boost/asio.hpp> -#include <iostream> - -#include "LibLsp/lsp/ProcessIoService.h" -#include "LibLsp/lsp/SimpleTimer.h" - - -using namespace boost::asio::ip; -using namespace std; - -struct ParentProcessWatcher::ParentProcessWatcherData : std::enable_shared_from_this<ParentProcessWatcherData> -{ - std::unique_ptr<SimpleTimer<boost::posix_time::seconds>> timer; - lsp::Log& _log; - std::function<void()> on_exit; - lsp::ProcessIoService asio_io; - std::shared_ptr < boost::process::opstream> write_to_service; - std::shared_ptr< boost::process::ipstream > read_from_service; - int pid; - const int _poll_delay_secs /*= 10*/; - std::string command; - std::shared_ptr<boost::process::child> c; - - ParentProcessWatcherData(lsp::Log& log, int _pid, - const std::function<void()>&& callback, uint32_t poll_delay_secs) : - _log(log), on_exit(callback), pid(_pid), _poll_delay_secs(poll_delay_secs) - { -#ifdef _WIN32 - command = "cmd /c \"tasklist /FI \"PID eq " + std::to_string(pid) + "\" | findstr " + - std::to_string(pid) + "\""; -#else - command = "ps -p " + std::to_string(pid); -#endif - - } - - void run() - { - write_to_service = std::make_shared<boost::process::opstream>(); - read_from_service = std::make_shared<boost::process::ipstream>(); - -// const uint32_t POLL_DELAY_SECS = _poll_delay_secs; - auto self(shared_from_this()); - std::error_code ec; - namespace bp = boost::process; - c = std::make_shared<bp::child>(asio_io.getIOService(), command, - ec, -#ifdef _WIN32 - bp::windows::hide, -#endif - bp::std_out > *read_from_service, - bp::std_in < *write_to_service, - bp::on_exit([self](int exit_code, const std::error_code& ec_in) { - // the tasklist command should return 0 (parent process exists) or 1 (parent process doesn't exist) - if (exit_code == 1)// - { - if (self->on_exit) - { - - std::thread([=]() - { - std::this_thread::sleep_for(std::chrono::seconds(3)); - self->on_exit(); - }).detach(); - } - } - else - { - if (exit_code > 1) - { - self->_log.log(lsp::Log::Level::WARNING, "The tasklist command: '" + self->command + "' returns " + std::to_string(exit_code)); - } - - self->timer = std::make_unique<SimpleTimer<boost::posix_time::seconds>>(self->_poll_delay_secs, [=]() { - self->run(); - }); - } - - })); - if (ec) - { - // fail - _log.log(lsp::Log::Level::SEVERE, "Start parent process watcher failed."); - } - } -}; - -ParentProcessWatcher::ParentProcessWatcher(lsp::Log& log, int pid, - const std::function<void()>&& callback, uint32_t poll_delay_secs) : d_ptr(new ParentProcessWatcherData(log, pid, std::move(callback), poll_delay_secs)) -{ - d_ptr->run(); -} - -ParentProcessWatcher::~ParentProcessWatcher() -{ - if (d_ptr->timer) - d_ptr->timer->Stop(); -} diff --git a/graphics/asymptote/LspCpp/src/lsp/ProtocolJsonHandler.cpp b/graphics/asymptote/LspCpp/src/lsp/ProtocolJsonHandler.cpp deleted file mode 100644 index c860b555af..0000000000 --- a/graphics/asymptote/LspCpp/src/lsp/ProtocolJsonHandler.cpp +++ /dev/null @@ -1,716 +0,0 @@ -#include "LibLsp/lsp/ProtocolJsonHandler.h" -#include "LibLsp/lsp/general/initialize.h" -#include "LibLsp/lsp/general/shutdown.h" -#include "LibLsp/lsp/textDocument/code_action.h" -#include "LibLsp/lsp/textDocument/code_lens.h" -#include "LibLsp/lsp/textDocument/completion.h" - - -#include "LibLsp/lsp/textDocument/did_close.h" - -#include "LibLsp/lsp/textDocument/highlight.h" -#include "LibLsp/lsp/textDocument/document_link.h" -#include "LibLsp/lsp/textDocument/formatting.h" -#include "LibLsp/lsp/textDocument/hover.h" -#include "LibLsp/lsp/textDocument/implementation.h" -#include "LibLsp/lsp/textDocument/range_formatting.h" -#include "LibLsp/lsp/textDocument/references.h" -#include "LibLsp/lsp/textDocument/rename.h" -#include "LibLsp/lsp/textDocument/signature_help.h" -#include "LibLsp/lsp/textDocument/type_definition.h" -#include "LibLsp/lsp/workspace/symbol.h" -#include "LibLsp/lsp/textDocument/typeHierarchy.h" -#include "LibLsp/lsp/out_list.h" -#include "LibLsp/lsp/extention/jdtls/codeActionResult.h" -#include "LibLsp/lsp/textDocument/declaration_definition.h" -#include "LibLsp/lsp/textDocument/resolveCompletionItem.h" -#include "LibLsp/lsp/textDocument/resolveCodeLens.h" -#include "LibLsp/lsp/textDocument/colorPresentation.h" -#include "LibLsp/lsp/textDocument/foldingRange.h" -#include "LibLsp/lsp/textDocument/prepareRename.h" -#include "LibLsp/lsp/textDocument/resolveTypeHierarchy.h" -#include "LibLsp/lsp/textDocument/callHierarchy.h" -#include "LibLsp/lsp/textDocument/selectionRange.h" -#include "LibLsp/lsp/extention/jdtls/classFileContents.h" -#include "LibLsp/lsp/extention/jdtls/buildWorkspace.h" -#include "LibLsp/lsp/extention/jdtls/listOverridableMethods.h" -#include "LibLsp/lsp/extention/jdtls/addOverridableMethods.h" -#include "LibLsp/lsp/extention/jdtls/checkHashCodeEqualsStatus.h" -#include "LibLsp/lsp/extention/jdtls/checkConstructorsStatus.h" -#include "LibLsp/lsp/extention/jdtls/checkDelegateMethodsStatus.h" -#include "LibLsp/lsp/extention/jdtls/checkToStringStatus.h" -#include "LibLsp/lsp/extention/jdtls/executeCommand.h" -#include "LibLsp/lsp/extention/jdtls/findLinks.h" -#include "LibLsp/lsp/extention/jdtls/generateAccessors.h" -#include "LibLsp/lsp/extention/jdtls/generateConstructors.h" -#include "LibLsp/lsp/extention/jdtls/generateDelegateMethods.h" -#include "LibLsp/lsp/extention/jdtls/generateHashCodeEquals.h" -#include "LibLsp/lsp/extention/jdtls/generateToString.h" -#include "LibLsp/lsp/extention/jdtls/getMoveDestinations.h" -#include "LibLsp/lsp/extention/jdtls/Move.h" -#include "LibLsp/lsp/extention/jdtls/organizeImports.h" -#include "LibLsp/lsp/general/exit.h" -#include "LibLsp/lsp/general/initialized.h" -#include "LibLsp/lsp/extention/jdtls/projectConfigurationUpdate.h" -#include "LibLsp/lsp/textDocument/did_change.h" -#include "LibLsp/lsp/textDocument/did_open.h" -#include "LibLsp/lsp/textDocument/did_save.h" -#include "LibLsp/lsp/textDocument/publishDiagnostics.h" -#include "LibLsp/lsp/textDocument/willSave.h" - -#include "LibLsp/lsp/workspace/didChangeWorkspaceFolders.h" -#include "LibLsp/lsp/workspace/did_change_configuration.h" -#include "LibLsp/lsp/workspace/did_change_watched_files.h" -#include "LibLsp/lsp/windows/MessageNotify.h" -#include "LibLsp/lsp/language/language.h" -#include "LibLsp/lsp/client/registerCapability.h" -#include "LibLsp/lsp/client/unregisterCapability.h" -#include "LibLsp/JsonRpc/Cancellation.h" -#include "LibLsp/lsp/textDocument/didRenameFiles.h" -#include "LibLsp/lsp/textDocument/semanticHighlighting.h" -#include "LibLsp/lsp/workspace/configuration.h" - - -void AddStadardResponseJsonRpcMethod(MessageJsonHandler& handler) -{ - - handler.method2response[td_initialize::request::kMethodInfo] = [](Reader& visitor) - { - if(visitor.HasMember("error")) - return Rsp_Error::ReflectReader(visitor); - - return td_initialize::response::ReflectReader(visitor); - }; - - handler.method2response[td_shutdown::request::kMethodInfo] = [](Reader& visitor) - { - if (visitor.HasMember("error")) - return Rsp_Error::ReflectReader(visitor); - return td_shutdown::response::ReflectReader(visitor); - }; - handler.method2response[td_codeAction::request::kMethodInfo] = [](Reader& visitor) - { - if (visitor.HasMember("error")) - return Rsp_Error::ReflectReader(visitor); - - return td_codeAction::response::ReflectReader(visitor); - }; - handler.method2response[td_codeLens::request::kMethodInfo] = [](Reader& visitor) - { - if (visitor.HasMember("error")) - return Rsp_Error::ReflectReader(visitor); - return td_codeLens::response::ReflectReader(visitor); - }; - handler.method2response[td_completion::request::kMethodInfo] = [](Reader& visitor) - { - if (visitor.HasMember("error")) - return Rsp_Error::ReflectReader(visitor); - return td_completion::response::ReflectReader(visitor); - }; - - handler.method2response[td_definition::request::kMethodInfo] = [](Reader& visitor) - { - if (visitor.HasMember("error")) - return Rsp_Error::ReflectReader(visitor); - return td_definition::response::ReflectReader(visitor); - }; - handler.method2response[td_declaration::request::kMethodInfo] = [](Reader& visitor) - { - if (visitor.HasMember("error")) - return Rsp_Error::ReflectReader(visitor); - return td_declaration::response::ReflectReader(visitor); - }; - handler.method2response[td_willSaveWaitUntil::request::kMethodInfo] = [](Reader& visitor) - { - if (visitor.HasMember("error")) - return Rsp_Error::ReflectReader(visitor); - return td_willSaveWaitUntil::response::ReflectReader(visitor); - }; - - handler.method2response[td_highlight::request::kMethodInfo] = [](Reader& visitor) - { - if (visitor.HasMember("error")) - return Rsp_Error::ReflectReader(visitor); - return td_highlight::response::ReflectReader(visitor); - }; - - handler.method2response[td_links::request::kMethodInfo] = [](Reader& visitor) - { - if (visitor.HasMember("error")) - return Rsp_Error::ReflectReader(visitor); - return td_links::response::ReflectReader(visitor); - }; - - handler.method2response[td_linkResolve::request::kMethodInfo] = [](Reader& visitor) - { - if (visitor.HasMember("error")) - return Rsp_Error::ReflectReader(visitor); - return td_linkResolve::response::ReflectReader(visitor); - }; - - handler.method2response[td_symbol::request::kMethodInfo] = [](Reader& visitor) - { - if (visitor.HasMember("error")) - return Rsp_Error::ReflectReader(visitor); - return td_symbol::response::ReflectReader(visitor); - }; - - handler.method2response[td_formatting::request::kMethodInfo] = [](Reader& visitor) - { - if (visitor.HasMember("error")) - return Rsp_Error::ReflectReader(visitor); - return td_formatting::response::ReflectReader(visitor); - }; - - handler.method2response[td_hover::request::kMethodInfo] = [](Reader& visitor) - { - if (visitor.HasMember("error")) - return Rsp_Error::ReflectReader(visitor); - return td_hover::response::ReflectReader(visitor); - - }; - - handler.method2response[td_implementation::request::kMethodInfo] = [](Reader& visitor) - { - if (visitor.HasMember("error")) - return Rsp_Error::ReflectReader(visitor); - return td_implementation::response::ReflectReader(visitor); - }; - - handler.method2response[td_rangeFormatting::request::kMethodInfo] = [](Reader& visitor) - { - if (visitor.HasMember("error")) - return Rsp_Error::ReflectReader(visitor); - return td_rangeFormatting::response::ReflectReader(visitor); - }; - - handler.method2response[td_references::request::kMethodInfo] = [](Reader& visitor) - { - if (visitor.HasMember("error")) - return Rsp_Error::ReflectReader(visitor); - return td_references::response::ReflectReader(visitor); - }; - - handler.method2response[td_rename::request::kMethodInfo] = [](Reader& visitor) - { - if (visitor.HasMember("error")) - return Rsp_Error::ReflectReader(visitor); - return td_rename::response::ReflectReader(visitor); - }; - - - handler.method2response[td_signatureHelp::request::kMethodInfo] = [](Reader& visitor) - { - if (visitor.HasMember("error")) - return Rsp_Error::ReflectReader(visitor); - return td_signatureHelp::response::ReflectReader(visitor); - }; - - handler.method2response[td_typeDefinition::request::kMethodInfo] = [](Reader& visitor) - { - if (visitor.HasMember("error")) - return Rsp_Error::ReflectReader(visitor); - return td_typeDefinition::response::ReflectReader(visitor); - }; - - handler.method2response[wp_executeCommand::request::kMethodInfo] = [](Reader& visitor) - { - if (visitor.HasMember("error")) - return Rsp_Error::ReflectReader(visitor); - return wp_executeCommand::response::ReflectReader(visitor); - }; - - handler.method2response[wp_symbol::request::kMethodInfo] = [](Reader& visitor) - { - if (visitor.HasMember("error")) - return Rsp_Error::ReflectReader(visitor); - return wp_symbol::response::ReflectReader(visitor); - }; - handler.method2response[td_typeHierarchy::request::kMethodInfo] = [](Reader& visitor) - { - if (visitor.HasMember("error")) - return Rsp_Error::ReflectReader(visitor); - return td_typeHierarchy::response::ReflectReader(visitor); - }; - handler.method2response[completionItem_resolve::request::kMethodInfo] = [](Reader& visitor) - { - if (visitor.HasMember("error")) - return Rsp_Error::ReflectReader(visitor); - return completionItem_resolve::response::ReflectReader(visitor); - }; - - handler.method2response[codeLens_resolve::request::kMethodInfo] = [](Reader& visitor) - { - if (visitor.HasMember("error")) - return Rsp_Error::ReflectReader(visitor); - - return codeLens_resolve::response::ReflectReader(visitor); - - }; - - handler.method2response[td_colorPresentation::request::kMethodInfo] = [](Reader& visitor) - { - if (visitor.HasMember("error")) - return Rsp_Error::ReflectReader(visitor); - - return td_colorPresentation::response::ReflectReader(visitor); - - }; - handler.method2response[td_documentColor::request::kMethodInfo] = [](Reader& visitor) - { - if (visitor.HasMember("error")) - return Rsp_Error::ReflectReader(visitor); - - return td_documentColor::response::ReflectReader(visitor); - - }; - handler.method2response[td_foldingRange::request::kMethodInfo] = [](Reader& visitor) - { - if (visitor.HasMember("error")) - return Rsp_Error::ReflectReader(visitor); - - return td_foldingRange::response::ReflectReader(visitor); - - }; - handler.method2response[td_prepareRename::request::kMethodInfo] = [](Reader& visitor) - { - if (visitor.HasMember("error")) - return Rsp_Error::ReflectReader(visitor); - - return td_prepareRename::response::ReflectReader(visitor); - - }; - handler.method2response[typeHierarchy_resolve::request::kMethodInfo] = [](Reader& visitor) - { - if (visitor.HasMember("error")) - return Rsp_Error::ReflectReader(visitor); - - return typeHierarchy_resolve::response::ReflectReader(visitor); - - }; - - handler.method2response[td_selectionRange::request::kMethodInfo] = [](Reader& visitor) - { - if (visitor.HasMember("error")) - return Rsp_Error::ReflectReader(visitor); - - return td_selectionRange::response::ReflectReader(visitor); - - }; - handler.method2response[td_didRenameFiles::request::kMethodInfo] = [](Reader& visitor) - { - if (visitor.HasMember("error")) - return Rsp_Error::ReflectReader(visitor); - - return td_didRenameFiles::response::ReflectReader(visitor); - - }; - handler.method2response[td_willRenameFiles::request::kMethodInfo] = [](Reader& visitor) - { - if (visitor.HasMember("error")) - return Rsp_Error::ReflectReader(visitor); - - return td_willRenameFiles::response::ReflectReader(visitor); - - }; - -} - - -void AddJavaExtentionResponseJsonRpcMethod(MessageJsonHandler& handler) -{ - handler.method2response[java_classFileContents::request::kMethodInfo] = [](Reader& visitor) - { - if (visitor.HasMember("error")) - return Rsp_Error::ReflectReader(visitor); - - return java_classFileContents::response::ReflectReader(visitor); - }; - handler.method2response[java_buildWorkspace::request::kMethodInfo] = [](Reader& visitor) - { - if (visitor.HasMember("error")) - return Rsp_Error::ReflectReader(visitor); - - return java_buildWorkspace::response::ReflectReader(visitor); - }; - handler.method2response[java_listOverridableMethods::request::kMethodInfo] = [](Reader& visitor) - { - if (visitor.HasMember("error")) - return Rsp_Error::ReflectReader(visitor); - - return java_listOverridableMethods::response::ReflectReader(visitor); - }; - handler.method2response[java_listOverridableMethods::request::kMethodInfo] = [](Reader& visitor) - { - if (visitor.HasMember("error")) - return Rsp_Error::ReflectReader(visitor); - - return java_listOverridableMethods::response::ReflectReader(visitor); - }; - - handler.method2response[java_checkHashCodeEqualsStatus::request::kMethodInfo] = [](Reader& visitor) - { - if (visitor.HasMember("error")) - return Rsp_Error::ReflectReader(visitor); - - return java_checkHashCodeEqualsStatus::response::ReflectReader(visitor); - }; - - - handler.method2response[java_addOverridableMethods::request::kMethodInfo] = [](Reader& visitor) - { - if (visitor.HasMember("error")) - return Rsp_Error::ReflectReader(visitor); - - return java_addOverridableMethods::response::ReflectReader(visitor); - }; - - handler.method2response[java_checkConstructorsStatus::request::kMethodInfo] = [](Reader& visitor) - { - if (visitor.HasMember("error")) - return Rsp_Error::ReflectReader(visitor); - - return java_checkConstructorsStatus::response::ReflectReader(visitor); - }; - - - handler.method2response[java_checkDelegateMethodsStatus::request::kMethodInfo] = [](Reader& visitor) - { - if (visitor.HasMember("error")) - return Rsp_Error::ReflectReader(visitor); - - return java_checkDelegateMethodsStatus::response::ReflectReader(visitor); - }; - handler.method2response[java_checkToStringStatus::request::kMethodInfo] = [](Reader& visitor) - { - if (visitor.HasMember("error")) - return Rsp_Error::ReflectReader(visitor); - - return java_checkToStringStatus::response::ReflectReader(visitor); - }; - - - handler.method2response[java_generateAccessors::request::kMethodInfo] = [](Reader& visitor) - { - if (visitor.HasMember("error")) - return Rsp_Error::ReflectReader(visitor); - - return java_generateAccessors::response::ReflectReader(visitor); - }; - handler.method2response[java_generateConstructors::request::kMethodInfo] = [](Reader& visitor) - { - if (visitor.HasMember("error")) - return Rsp_Error::ReflectReader(visitor); - - return java_generateConstructors::response::ReflectReader(visitor); - }; - handler.method2response[java_generateDelegateMethods::request::kMethodInfo] = [](Reader& visitor) - { - if (visitor.HasMember("error")) - return Rsp_Error::ReflectReader(visitor); - - return java_generateDelegateMethods::response::ReflectReader(visitor); - }; - - handler.method2response[java_generateHashCodeEquals::request::kMethodInfo] = [](Reader& visitor) - { - if (visitor.HasMember("error")) - return Rsp_Error::ReflectReader(visitor); - - return java_generateHashCodeEquals::response::ReflectReader(visitor); - }; - handler.method2response[java_generateToString::request::kMethodInfo] = [](Reader& visitor) - { - if (visitor.HasMember("error")) - return Rsp_Error::ReflectReader(visitor); - - return java_generateToString::response::ReflectReader(visitor); - }; - - handler.method2response[java_generateToString::request::kMethodInfo] = [](Reader& visitor) - { - if (visitor.HasMember("error")) - return Rsp_Error::ReflectReader(visitor); - - return java_generateToString::response::ReflectReader(visitor); - }; - - handler.method2response[java_getMoveDestinations::request::kMethodInfo] = [](Reader& visitor) - { - if (visitor.HasMember("error")) - return Rsp_Error::ReflectReader(visitor); - - return java_getMoveDestinations::response::ReflectReader(visitor); - }; - - handler.method2response[java_getRefactorEdit::request::kMethodInfo] = [](Reader& visitor) - { - if (visitor.HasMember("error")) - return Rsp_Error::ReflectReader(visitor); - - return java_getRefactorEdit::response::ReflectReader(visitor); - }; - - handler.method2response[java_move::request::kMethodInfo] = [](Reader& visitor) - { - if (visitor.HasMember("error")) - return Rsp_Error::ReflectReader(visitor); - - return java_move::response ::ReflectReader(visitor); - }; - - handler.method2response[java_organizeImports::request::kMethodInfo] = [](Reader& visitor) - { - if (visitor.HasMember("error")) - return Rsp_Error::ReflectReader(visitor); - - return java_organizeImports::response::ReflectReader(visitor); - }; - - handler.method2response[java_resolveUnimplementedAccessors::request::kMethodInfo] = [](Reader& visitor) - { - if (visitor.HasMember("error")) - return Rsp_Error::ReflectReader(visitor); - - return java_resolveUnimplementedAccessors::response::ReflectReader(visitor); - }; - - handler.method2response[java_searchSymbols::request::kMethodInfo] = [](Reader& visitor) - { - if (visitor.HasMember("error")) - return Rsp_Error::ReflectReader(visitor); - - return java_searchSymbols::response::ReflectReader(visitor); - }; - - handler.method2request[WorkspaceConfiguration::request::kMethodInfo] = [](Reader& visitor) - { - return WorkspaceConfiguration::request::ReflectReader(visitor); - }; - handler.method2request[WorkspaceFolders::request::kMethodInfo] = [](Reader& visitor) - { - return WorkspaceFolders::request::ReflectReader(visitor); - }; - -} - -void AddNotifyJsonRpcMethod(MessageJsonHandler& handler) -{ - - handler.method2notification[Notify_Exit::notify::kMethodInfo] = [](Reader& visitor) - { - return Notify_Exit::notify::ReflectReader(visitor); - }; - handler.method2notification[Notify_InitializedNotification::notify::kMethodInfo] = [](Reader& visitor) - { - return Notify_InitializedNotification::notify::ReflectReader(visitor); - }; - - handler.method2notification[java_projectConfigurationUpdate::notify::kMethodInfo] = [](Reader& visitor) - { - return java_projectConfigurationUpdate::notify::ReflectReader(visitor); - }; - - handler.method2notification[Notify_TextDocumentDidChange::notify::kMethodInfo] = [](Reader& visitor) - { - return Notify_TextDocumentDidChange::notify::ReflectReader(visitor); - }; - - handler.method2notification[Notify_TextDocumentDidClose::notify::kMethodInfo] = [](Reader& visitor) - { - return Notify_TextDocumentDidClose::notify::ReflectReader(visitor); - }; - - - handler.method2notification[Notify_TextDocumentDidOpen::notify::kMethodInfo] = [](Reader& visitor) - { - return Notify_TextDocumentDidOpen::notify::ReflectReader(visitor); - }; - - handler.method2notification[Notify_TextDocumentDidSave::notify::kMethodInfo] = [](Reader& visitor) - { - return Notify_TextDocumentDidSave::notify::ReflectReader(visitor); - }; - - handler.method2notification[Notify_TextDocumentPublishDiagnostics::notify::kMethodInfo] = [](Reader& visitor) - { - return Notify_TextDocumentPublishDiagnostics::notify::ReflectReader(visitor); - }; - handler.method2notification[Notify_semanticHighlighting::notify::kMethodInfo] = [](Reader& visitor) - { - return Notify_semanticHighlighting::notify::ReflectReader(visitor); - }; - handler.method2notification[td_willSave::notify::kMethodInfo] = [](Reader& visitor) - { - return td_willSave::notify::ReflectReader(visitor); - }; - - handler.method2notification[Notify_LogMessage::notify::kMethodInfo] = [](Reader& visitor) - { - return Notify_LogMessage::notify::ReflectReader(visitor); - }; - handler.method2notification[Notify_ShowMessage::notify::kMethodInfo] = [](Reader& visitor) - { - return Notify_ShowMessage::notify::ReflectReader(visitor); - }; - handler.method2notification[Notify_WorkspaceDidChangeWorkspaceFolders::notify::kMethodInfo] = [](Reader& visitor) - { - return Notify_WorkspaceDidChangeWorkspaceFolders::notify::ReflectReader(visitor); - }; - - handler.method2notification[Notify_WorkspaceDidChangeConfiguration::notify::kMethodInfo] = [](Reader& visitor) - { - return Notify_WorkspaceDidChangeConfiguration::notify::ReflectReader(visitor); - }; - - - handler.method2notification[Notify_WorkspaceDidChangeWatchedFiles::notify::kMethodInfo] = [](Reader& visitor) - { - return Notify_WorkspaceDidChangeWatchedFiles::notify::ReflectReader(visitor); - }; - - handler.method2notification[Notify_sendNotification::notify::kMethodInfo] = [](Reader& visitor) - { - return Notify_sendNotification::notify::ReflectReader(visitor); - }; - handler.method2notification[lang_status::notify::kMethodInfo] = [](Reader& visitor) - { - return lang_status::notify::ReflectReader(visitor); - }; - handler.method2notification[lang_actionableNotification::notify::kMethodInfo] = [](Reader& visitor) - { - return lang_actionableNotification::notify::ReflectReader(visitor); - }; - handler.method2notification[lang_progressReport::notify::kMethodInfo] = [](Reader& visitor) - { - return lang_progressReport::notify::ReflectReader(visitor); - }; - handler.method2notification[lang_eventNotification::notify::kMethodInfo] = [](Reader& visitor) - { - return lang_eventNotification::notify::ReflectReader(visitor); - }; -} - -void AddRequstJsonRpcMethod(MessageJsonHandler& handler) -{ - handler.method2request[Req_ClientRegisterCapability::request::kMethodInfo]= [](Reader& visitor) - { - - return Req_ClientRegisterCapability::request::ReflectReader(visitor); - }; - handler.method2request[Req_ClientUnregisterCapability::request::kMethodInfo] = [](Reader& visitor) - { - - return Req_ClientUnregisterCapability::request::ReflectReader(visitor); - }; -} - -void AddStandardRequestJsonRpcMethod(MessageJsonHandler& handler) -{ - - handler.method2request[td_initialize::request::kMethodInfo] = [](Reader& visitor) - { - - return td_initialize::request::ReflectReader(visitor); - }; - handler.method2request[td_shutdown::request::kMethodInfo] = [](Reader& visitor) - { - - return td_shutdown::request::ReflectReader(visitor); - }; - handler.method2request[td_codeAction::request::kMethodInfo] = [](Reader& visitor) - { - - - return td_codeAction::request::ReflectReader(visitor); - }; - handler.method2request[td_codeLens::request::kMethodInfo] = [](Reader& visitor) - { - - return td_codeLens::request::ReflectReader(visitor); - }; - handler.method2request[td_completion::request::kMethodInfo] = [](Reader& visitor) - { - - return td_completion::request::ReflectReader(visitor); - }; - - handler.method2request[td_definition::request::kMethodInfo] = [](Reader& visitor) - { - - return td_definition::request::ReflectReader(visitor); - }; - handler.method2request[td_declaration::request::kMethodInfo] = [](Reader& visitor) - { - - return td_declaration::request::ReflectReader(visitor); - }; - handler.method2request[td_willSaveWaitUntil::request::kMethodInfo] = [](Reader& visitor) - { - if (visitor.HasMember("error")) - return Rsp_Error::ReflectReader(visitor); - return td_willSaveWaitUntil::request::ReflectReader(visitor); - }; - - handler.method2request[td_highlight::request::kMethodInfo] = [](Reader& visitor) - { - - return td_highlight::request::ReflectReader(visitor); - }; - - handler.method2request[td_links::request::kMethodInfo] = [](Reader& visitor) - { - - return td_links::request::ReflectReader(visitor); - }; - - handler.method2request[td_linkResolve::request::kMethodInfo] = [](Reader& visitor) - { - - return td_linkResolve::request::ReflectReader(visitor); - }; - - handler.method2request[td_symbol::request::kMethodInfo] = [](Reader& visitor) - { - - return td_symbol::request::ReflectReader(visitor); - }; - - handler.method2request[td_formatting::request::kMethodInfo] = [](Reader& visitor) - { - - return td_formatting::request::ReflectReader(visitor); - }; - - handler.method2request[td_hover::request::kMethodInfo] = [](Reader& visitor) - { - return td_hover::request::ReflectReader(visitor); - }; - - handler.method2request[td_implementation::request::kMethodInfo] = [](Reader& visitor) - { - - return td_implementation::request::ReflectReader(visitor); - }; - - handler.method2request[td_didRenameFiles::request::kMethodInfo] = [](Reader& visitor) - { - - return td_didRenameFiles::request::ReflectReader(visitor); - }; - - handler.method2request[td_willRenameFiles::request::kMethodInfo] = [](Reader& visitor) - { - return td_willRenameFiles::request::ReflectReader(visitor); - }; -} - - -lsp::ProtocolJsonHandler::ProtocolJsonHandler() -{ - AddStadardResponseJsonRpcMethod(*this); - AddJavaExtentionResponseJsonRpcMethod(*this); - AddNotifyJsonRpcMethod(*this); - AddStandardRequestJsonRpcMethod(*this); - AddRequstJsonRpcMethod(*this); -} diff --git a/graphics/asymptote/LspCpp/src/lsp/initialize.cpp b/graphics/asymptote/LspCpp/src/lsp/initialize.cpp deleted file mode 100644 index 504caa3e65..0000000000 --- a/graphics/asymptote/LspCpp/src/lsp/initialize.cpp +++ /dev/null @@ -1,45 +0,0 @@ -#include "LibLsp/lsp/general/initialize.h" -#include "LibLsp/JsonRpc/json.h" - -void Reflect(Reader& reader, lsInitializeParams::lsTrace& value) -{ - if (!reader.IsString()) - { - value = lsInitializeParams::lsTrace::Off; - return; - } - std::string v = reader.GetString(); - if (v == "off") - value = lsInitializeParams::lsTrace::Off; - else if (v == "messages") - value = lsInitializeParams::lsTrace::Messages; - else if (v == "verbose") - value = lsInitializeParams::lsTrace::Verbose; -} - -void Reflect(Writer& writer, lsInitializeParams::lsTrace& value) -{ - switch (value) - { - case lsInitializeParams::lsTrace::Off: - writer.String("off"); - break; - case lsInitializeParams::lsTrace::Messages: - writer.String("messages"); - break; - case lsInitializeParams::lsTrace::Verbose: - writer.String("verbose"); - break; - } -} - void Reflect(Reader& visitor, std::pair<optional<lsTextDocumentSyncKind>, optional<lsTextDocumentSyncOptions> >& value) -{ - if(((JsonReader&)visitor).m_->IsObject()) - { - Reflect(visitor, value.second); - } - else - { - Reflect(visitor, value.first); - } -} diff --git a/graphics/asymptote/LspCpp/src/lsp/lsp.cpp b/graphics/asymptote/LspCpp/src/lsp/lsp.cpp deleted file mode 100644 index d070f22be1..0000000000 --- a/graphics/asymptote/LspCpp/src/lsp/lsp.cpp +++ /dev/null @@ -1,1089 +0,0 @@ - - -#include "LibLsp/lsp/lru_cache.h" - - -#include <rapidjson/writer.h> - - -#include <stdio.h> -#include <iostream> -#include "LibLsp/lsp/location_type.h" -#include "LibLsp/lsp/out_list.h" -#include "LibLsp/lsp/lsTextDocumentIdentifier.h" -#include "LibLsp/lsp/lsVersionedTextDocumentIdentifier.h" -#include "LibLsp/lsp/lsResponseError.h" -#include "LibLsp/lsp/lsPosition.h" -#include "LibLsp/lsp/lsTextEdit.h" -#include "LibLsp/lsp/lsMarkedString.h" -#include "LibLsp/lsp/lsWorkspaceEdit.h" -#include "LibLsp/lsp/textDocument/code_action.h" -#include "LibLsp/lsp/textDocument/document_symbol.h" -#include "LibLsp/lsp/extention/jdtls/codeActionResult.h" - -#include "LibLsp/lsp/textDocument/selectionRange.h" -#include "LibLsp/lsp/AbsolutePath.h" - -#ifdef _WIN32 -#include <Windows.h> -#else -#include <climits> -#include <cstdlib> -#endif - -#include "LibLsp/lsp/Directory.h" -#include "LibLsp/lsp/lsFormattingOptions.h" -#include "LibLsp/JsonRpc/json.h" -#include "LibLsp/lsp/language/language.h" - -#include <network/uri/uri_builder.hpp> - -#include "LibLsp/lsp/lsp_completion.h" -#include "LibLsp/lsp/utils.h" -#include "LibLsp/lsp/client/registerCapability.h" -#include <boost/uuid/uuid.hpp> -#include <boost/uuid/uuid_io.hpp> -#include <boost/uuid/uuid_generators.hpp> -// namespace - - - -lsTextDocumentIdentifier -lsVersionedTextDocumentIdentifier::AsTextDocumentIdentifier() const { - lsTextDocumentIdentifier result; - result.uri = uri; - return result; -} - - -lsPosition::lsPosition() {} -lsPosition::lsPosition(int line, int character) - : line(line), character(character) {} - -bool lsPosition::operator==(const lsPosition& other) const { - return line == other.line && character == other.character; -} - -bool lsPosition::operator<(const lsPosition& other) const { - return line != other.line ? line < other.line : character < other.character; -} - -std::string lsPosition::ToString() const { - return std::to_string(line) + ":" + std::to_string(character); -} -const lsPosition lsPosition::kZeroPosition = lsPosition(); - -lsRange::lsRange() {} -lsRange::lsRange(lsPosition start, lsPosition end) : start(start), end(end) {} - -bool lsRange::operator==(const lsRange& o) const { - return start == o.start && end == o.end; -} - -bool lsRange::operator<(const lsRange& o) const { - return !(start == o.start) ? start < o.start : end < o.end; -} - -std::string lsRange::ToString() const -{ - std::stringstream ss; - ss << "start:" << start.ToString() << std::endl; - ss << "end" << end.ToString() << std::endl; - return ss.str(); -} - -lsLocation::lsLocation() {} -lsLocation::lsLocation(lsDocumentUri uri, lsRange range) - : uri(uri), range(range) {} - -bool lsLocation::operator==(const lsLocation& o) const { - return uri == o.uri && range == o.range; -} - -bool lsLocation::operator<(const lsLocation& o) const { - return std::make_tuple(uri.raw_uri_, range) < - std::make_tuple(o.uri.raw_uri_, o.range); -} - -bool lsTextEdit::operator==(const lsTextEdit& that) { - return range == that.range && newText == that.newText; -} - -std::string lsTextEdit::ToString() const -{ - std::stringstream ss; - ss << "Range:" << range.ToString() << std::endl; - ss << "newText:" << newText << std::endl; - return ss.str(); -} - -void Reflect(Writer& visitor, lsMarkedString& value) { - // If there is a language, emit a `{language:string, value:string}` object. If - // not, emit a string. - if (value.language) { - REFLECT_MEMBER_START(); - REFLECT_MEMBER(language); - REFLECT_MEMBER(value); - REFLECT_MEMBER_END(); - } else { - Reflect(visitor, value.value); - } -} - -void Reflect(Reader& visitor, lsMarkedString& value) -{ - REFLECT_MEMBER_START(); - REFLECT_MEMBER(language); - REFLECT_MEMBER(value); - REFLECT_MEMBER_END(); -} - - void Reflect(Reader& visitor, LocationListEither::Either& value) -{ - if(!visitor.IsArray()) - { - throw std::invalid_argument("Rsp_LocationListEither::Either& value is not array"); - } - auto data = ((JsonReader&)visitor).m_->GetArray(); - if (data.Size() && data[0].HasMember("originSelectionRange")) - { - Reflect(visitor, value.second); - } - else { - Reflect(visitor, value.first); - } - -} - - void Reflect(Writer& visitor, LocationListEither::Either& value) -{ - if (value.first) - { - Reflect(visitor, value.first.value()); - } - else if (value.second) - { - Reflect(visitor, value.second.value()); - } -} - - -void Reflect(Reader& visitor, TextDocumentCodeAction::Either& value) -{ - - - if(visitor.HasMember("command")) - { - if(visitor["command"]->IsString()) - { - Reflect(visitor, value.first); - } - else - { - Reflect(visitor, value.second); - } - } - else - { - if (visitor.HasMember("diagnostics") || visitor.HasMember("edit")) - { - Reflect(visitor, value.second); - } - else - { - Reflect(visitor, value.first); - } - } - -} - - -void Reflect(Reader& visitor, lsWorkspaceEdit::Either& value) -{ - - - if(visitor.HasMember("textDocument")) - { - Reflect(visitor, value.first); - } - else - { - Reflect(visitor, value.second); - } -} -ResourceOperation* GetResourceOperation(lsp::Any& lspAny) -{ - rapidjson::Document document; - auto& data = lspAny.Data(); - document.Parse(data.c_str(), data.length()); - if (document.HasParseError()) { - // ��ʾ - return nullptr; - } - auto find = document.FindMember("kind"); - - JsonReader visitor{ &document }; - try - { - if (find->value == "create") - { - auto ptr = std::make_unique<lsCreateFile>(); - auto temp = ptr.get(); - Reflect(visitor, *temp); - return ptr.release(); - } - else if (find->value == "rename") - { - auto ptr = std::make_unique<lsRenameFile>(); - auto temp = ptr.get(); - Reflect(visitor, *temp); - return ptr.release(); - } - else if (find->value == "delete") - { - - auto ptr = std::make_unique<lsDeleteFile>(); - auto temp = ptr.get(); - Reflect(visitor, *temp); - return ptr.release(); - } - } - catch (std::exception&) - { - - } - return nullptr; -} - - void Reflect(Writer& visitor, ResourceOperation* value) -{ - - if(!value) - { - throw std::invalid_argument("ResourceOperation value is nullptr"); - } - if (value->kind == "create") - { - auto temp = (lsCreateFile*)value; - Reflect(visitor, *temp); - } - else if (value->kind == "rename") - { - auto temp = (lsRenameFile*)value; - Reflect(visitor, *temp); - } - else if (value->kind == "delete") - { - - auto temp = (lsDeleteFile*)value; - Reflect(visitor, *temp); - } - -} - -int lsp::Any::GuessType() -{ - if (!data.empty()) - { - if (data == "null") - { - jsonType = rapidjson::kNullType; - } - else if (data == "true") - { - jsonType = rapidjson::kTrueType; - } - else if(data == "false") - { - jsonType = rapidjson::kFalseType; - } - else if (data[0] == '{') - { - jsonType = rapidjson::kObjectType; - } - else if (data[0] == '[') - { - if (data.size() >= 2 && data[1] == '{') - jsonType = rapidjson::kStringType; - else - jsonType = rapidjson::kArrayType; - } - else if (data[0] == '"') - { - jsonType = rapidjson::kStringType; - } - else - { - jsonType = rapidjson::kNumberType; - } - } - else - { - if (jsonType != kUnKnown) - return jsonType; - jsonType = rapidjson::kNullType; - } - return jsonType; -} - -int lsp::Any::GetType() -{ - if (jsonType == Type::kUnKnown) - { - if (data.empty()) - { - jsonType = rapidjson::kNullType; - return jsonType; - } - rapidjson::Document document; - document.Parse(data.c_str(), data.length()); - if (document.HasParseError()) - { - // ��ʾ - return jsonType; - } - jsonType = document.GetType(); - } - return jsonType; -} - -void lsp::Any::Set(std::unique_ptr<LspMessage> value) -{ - if (value) - { - jsonType = rapidjson::Type::kObjectType; - data = value->ToJson(); - } - else - { - assert(false); - } -} - -void lsp::Any::SetJsonString(std::string&& _data, Type _type) -{ - jsonType = _type; - data.swap(_data); - GetType(); -} - -void lsp::Any::SetJsonString(const std::string& _data, Type _type) -{ - jsonType = _type; - data = (_data); - GetType(); -} - -void lsp::Any::swap(Any& arg) noexcept -{ - data.swap(arg.data); - const int temp = jsonType; - jsonType = arg.jsonType; - arg.jsonType = temp; -} - -class JsonReaderForAny : public JsonReader -{ -public: - JsonReaderForAny() - : JsonReader(&document) - { - } - rapidjson::Document document; -}; - -bool lsp::Any::GetForMapHelper(std::string& value) -{ - return Get(value); -} - -bool lsp::Any::GetForMapHelper(optional<std::string>& value) -{ - return Get(value); -} - -std::unique_ptr<Reader> lsp::Any::GetReader() -{ - auto reader = new JsonReaderForAny(); - std::unique_ptr<Reader> ret(reader); - reader->document.Parse(data.c_str(), data.length()); - if (reader->document.HasParseError()) - { - return {}; - } - if (jsonType == kUnKnown) - { - jsonType = reader->document.GetType(); - } - return (ret); -} - -class JsonWriterForAny : public JsonWriter -{ -public: - rapidjson::StringBuffer output; - rapidjson::Writer<rapidjson::StringBuffer> writer; - JsonWriterForAny():JsonWriter(&writer), writer(output) - { - - } -}; - -std::unique_ptr<Writer> lsp::Any::GetWriter() const -{ - return std::make_unique<JsonWriterForAny>(); -} - -void lsp::Any::SetData(std::unique_ptr<Writer>& writer) -{ - auto _temp = static_cast<JsonWriterForAny*>(writer.get()); - data = _temp->output.GetString(); - GuessType(); -} - -namespace -{ -#if 0 - rapidjson::Type convert(lsp::Any::Type type) - { - switch (type) - { - case lsp::Any::Type::kNullType: - return rapidjson::Type::kNullType; - case lsp::Any::Type::kFalseType: - return rapidjson::Type::kFalseType; - case lsp::Any::Type::kTrueType: - return rapidjson::Type::kTrueType; - case lsp::Any::Type::kObjectType: - return rapidjson::Type::kObjectType; - case lsp::Any::Type::kArrayType: - return rapidjson::Type::kArrayType; - case lsp::Any::Type::kStringType: - return rapidjson::Type::kStringType; - case lsp::Any::Type::kNumberType: - return rapidjson::Type::kNumberType; - default: - return rapidjson::Type::kNullType; - } - } -#endif - lsp::Any::Type convert(rapidjson::Type type) - { - switch (type) - { - case rapidjson::Type::kNullType: - return lsp::Any::Type::kNullType; - case rapidjson::Type::kFalseType: - return lsp::Any::Type::kFalseType; - case rapidjson::Type::kTrueType: - return lsp::Any::Type::kTrueType; - case rapidjson::Type::kObjectType: - return lsp::Any::Type::kObjectType; - case rapidjson::Type::kArrayType: - return lsp::Any::Type::kArrayType; - case rapidjson::Type::kStringType: - return lsp::Any::Type::kStringType; - case rapidjson::Type::kNumberType: - return lsp::Any::Type::kNumberType; - default: - return lsp::Any::Type::kNullType; - } - } -} - -void Reflect(Reader& visitor, lsp::Any& value) -{ - - //if (visitor.IsNull()) { - // visitor.GetNull(); - // value.SetJsonString("", rapidjson::Type::kNullType); - // return; - //}else - //{ - // - //} - JsonReader& json_reader = reinterpret_cast<JsonReader&>(visitor); - value.SetJsonString(visitor.ToString(), convert(json_reader.m_->GetType())); -} - void Reflect(Writer& visitor, lsp::Any& value) - { - JsonWriter& json_writer = reinterpret_cast<JsonWriter&>(visitor); - json_writer.m_->RawValue( value.Data().data(),value.Data().size(),static_cast<rapidjson::Type>(value.GetType())); - - } - void Reflect(Reader& visitor, lsFormattingOptions::KeyData& value) -{ - if (visitor.IsBool()) - { - Reflect(visitor, value._boolean); - } - else if (visitor.IsInt() || visitor.IsInt64() || visitor.IsUint64()) - { - Reflect(visitor, value._integer); - } - else if(visitor.IsString()) - { - Reflect(visitor, value._string); - } -} - void Reflect(Writer& visitor, lsFormattingOptions::KeyData& value) -{ - if (value._boolean.has_value()) - { - Reflect(visitor, value._boolean); - } - else if (value._integer.has_value()) - { - Reflect(visitor, value._integer); - } - else if (value._string.has_value()) - { - Reflect(visitor, value._string); - } -} - -lsCreateFile::lsCreateFile() -{ - kind = "create"; -} - -lsDeleteFile::lsDeleteFile() -{ - kind = "delete"; -} - -lsRenameFile::lsRenameFile() -{ - kind = "rename"; -} - - -void Reflect(Reader& visitor, optional< SelectionRange* >& value) -{ - if (visitor.IsNull()) { - visitor.GetNull(); - return; - } - - SelectionRange* entry_value = nullptr; - - - std::unique_ptr<SelectionRange> ptr = std::make_unique<SelectionRange>(); - SelectionRange* temp = ptr.get(); - Reflect(visitor, *temp); - - entry_value = ptr.release(); - value = (entry_value); - -} -void Reflect(Writer& visitor, SelectionRange* value) -{ - - if (!value) - { - throw std::invalid_argument("ResourceOperation value is nullptr"); - } - - Reflect(visitor, *value); - - -} - - std::string make_file_scheme_uri(const std::string& absolute_path) -{ - network::uri_builder builder; - builder.scheme("file"); - builder.host(""); - builder.path(absolute_path); - return builder.uri().string(); - //// lsDocumentUri uri; - //// uri.SetPath(absolute_path); - /// return uri.raw_uri_; -} - -// static -AbsolutePath AbsolutePath::BuildDoNotUse(const std::string& path) { - AbsolutePath p; - p.path = std::string(path); - return p; -} - - -AbsolutePath::AbsolutePath() {} - - - -AbsolutePath::operator std::string() const { - return path; -} - -bool AbsolutePath::operator==(const AbsolutePath& rhs) const { - return path == rhs.path; -} - -bool AbsolutePath::operator!=(const AbsolutePath& rhs) const { - return path != rhs.path; -} - -bool AbsolutePath::operator<(const AbsolutePath& rhs) const -{ - return path < rhs.path; -} - -bool AbsolutePath::operator>(const AbsolutePath& rhs) const -{ - return path > rhs.path; -} - -void Reflect(Reader& visitor, AbsolutePath& value) { - value.path = visitor.GetString(); -} -void Reflect(Writer& visitor, AbsolutePath& value) { - visitor.String(value.path.c_str(), value.path.length()); -} - -std::ostream& operator<<(std::ostream& out, const AbsolutePath& path) { - out << path.path; - return out; -} - -lsDocumentUri lsDocumentUri::FromPath(const AbsolutePath& path) { - lsDocumentUri result; - result.SetPath(path); - return result; -} -//void lsDocumentUri::SetPath(const AbsolutePath& path) -//{ -// raw_uri_ = make_file_scheme_uri(path.path); -//} -// -void lsDocumentUri::SetPath(const AbsolutePath& path) { - // file:///c%3A/Users/jacob/Desktop/superindex/indexer/full_tests - raw_uri_ = path; - - size_t index = raw_uri_.find(":"); - if (index == 1) { // widows drive letters must always be 1 char - raw_uri_.replace(raw_uri_.begin() + index, raw_uri_.begin() + index + 1, - "%3A"); - } - - // subset of reserved characters from the URI standard - // http://www.ecma-international.org/ecma-262/6.0/#sec-uri-syntax-and-semantics - std::string t; - t.reserve(8 + raw_uri_.size()); - - // TODO: proper fix -#if defined(_WIN32) - t += "file:///"; -#else - t += "file://"; -#endif - - // clang-format off - for (char c : raw_uri_) - switch (c) { - case ' ': t += "%20"; break; - case '#': t += "%23"; break; - case '$': t += "%24"; break; - case '&': t += "%26"; break; - case '(': t += "%28"; break; - case ')': t += "%29"; break; - case '+': t += "%2B"; break; - case ',': t += "%2C"; break; - case ';': t += "%3B"; break; - case '?': t += "%3F"; break; - case '@': t += "%40"; break; - default: t += c; break; - } - // clang-format on - raw_uri_ = std::move(t); -} - -std::string lsDocumentUri::GetRawPath() const { - - - if (raw_uri_.compare(0, 8, "file:///")) - return raw_uri_; - - - std::string ret; -#if defined(_WIN32) - size_t i = 8; -#else - size_t i = 7; -#endif - auto from_hex = [](unsigned char c) { - return c - '0' < 10 ? c - '0' : (c | 32) - 'a' + 10; - }; - for (; i < raw_uri_.size(); i++) { - if (i + 3 <= raw_uri_.size() && raw_uri_[i] == '%') { - ret.push_back(from_hex(raw_uri_[i + 1]) * 16 + from_hex(raw_uri_[i + 2])); - i += 2; - } - else - ret.push_back(raw_uri_[i] == '\\' ? '/' : raw_uri_[i]); - } - return ret; -} - -lsDocumentUri::lsDocumentUri() {} - - -lsDocumentUri::lsDocumentUri(const AbsolutePath& path) -{ - SetPath(path); -} - -lsDocumentUri::lsDocumentUri(const lsDocumentUri& other): raw_uri_(other.raw_uri_) -{ -} - -bool lsDocumentUri::operator==(const lsDocumentUri& other) const { - return raw_uri_ == other.raw_uri_; -} - -bool lsDocumentUri::operator==(const std::string& other) const -{ - return raw_uri_ == other; -} - - -AbsolutePath lsDocumentUri::GetAbsolutePath() const { - - - if (raw_uri_.find("file://") != std::string::npos){ - try - { - return lsp::NormalizePath(GetRawPath(), false /*ensure_exists*/, false); - } - catch (std::exception&) - { - return AbsolutePath("", false); - } - } - - return AbsolutePath(raw_uri_,false); - -} - -AbsolutePath::AbsolutePath(const std::string& path, bool validate) - : path(path) { - // TODO: enable validation after fixing tests. - if (validate && !lsp::IsAbsolutePath(path)) { - qualify = false; - auto temp = lsp::NormalizePath(path,false); - if(!temp.path.empty()) - { - this->path = temp.path; - } - } -} - -void Reflect(Writer& visitor, lsDocumentUri& value) { - Reflect(visitor, value.raw_uri_); -} -void Reflect(Reader& visitor, lsDocumentUri& value) { - Reflect(visitor, value.raw_uri_); - // Only record the path when we deserialize a URI, since it most likely came - // from the client. - -} - - std::string ProgressReport::ToString() const -{ - std::string info; - info += "id:" + id + "\n"; - info += "task:" + task + "\n"; - info += "subTask:" + subTask + "\n"; - info += "status:" + status + "\n"; - { - std::stringstream ss; - ss << "totalWork:" << totalWork << std::endl; - info += ss.str(); - } - { - std::stringstream ss; - ss << "workDone:" << workDone << std::endl; - info += ss.str(); - } - - { - std::stringstream ss; - ss << "complete:" << complete << std::endl; - info += ss.str(); - } - - return info; -} - -std::string EventNotification::ToString() const -{ - std::string info; - if (ClasspathUpdated == eventType) - { - info += "eventType:ClasspathUpdated\n"; - } - else if (ProjectsImported == eventType) - { - info += "eventType:ProjectsImported\n"; - } - else - { - std::ostringstream oss; - oss << std::hex << eventType << std::endl; - - info += "eventType:"; - info += oss.str(); - } - info += "data:" + data.Data() + "\n"; - return info; -} - -std::string lsp::ToString(lsCompletionItemKind _kind) -{ - switch (_kind) { - case lsCompletionItemKind::Text: - return "Text"; - case lsCompletionItemKind::Method: - return "Method"; - case lsCompletionItemKind::Function: - return ""; - case lsCompletionItemKind::Constructor: - return "Function"; - case lsCompletionItemKind::Field: - return "Field"; - case lsCompletionItemKind::Variable: - return ""; - case lsCompletionItemKind::Class: - return "Variable"; - case lsCompletionItemKind::Interface: - return "Interface"; - case lsCompletionItemKind::Module: - return "Module"; - case lsCompletionItemKind::Property: - return "Property"; - case lsCompletionItemKind::Unit: - return "Unit"; - case lsCompletionItemKind::Value: - return "Value"; - case lsCompletionItemKind::Enum: - return "Enum"; - case lsCompletionItemKind::Keyword: - return "Keyword"; - case lsCompletionItemKind::Snippet: - return "Snippet"; - case lsCompletionItemKind::Color: - return "Color"; - case lsCompletionItemKind::File: - return "File"; - case lsCompletionItemKind::Reference: - return "Reference"; - case lsCompletionItemKind::Folder: - return "Folder"; - case lsCompletionItemKind::EnumMember: - return "EnumMember"; - case lsCompletionItemKind::Constant: - return "Constant"; - case lsCompletionItemKind::Struct: - return "Struct"; - case lsCompletionItemKind::Event: - return "Event"; - case lsCompletionItemKind::Operator: - return "Operator"; - case lsCompletionItemKind::TypeParameter: - return "TypeParameter"; - default: - return "Unknown"; - } -} - -std::string lsp::ToString(lsInsertTextFormat _kind) -{ - if (_kind == lsInsertTextFormat::PlainText) - { - return "PlainText"; - } - else if (_kind == lsInsertTextFormat::Snippet) - { - return "Snippet"; - }else - { - return "Unknown"; - } -} - -const std::string& lsCompletionItem::InsertedContent() const -{ - if (textEdit) - return textEdit->newText; - if (insertText.has_value() && !insertText->empty()) - return insertText.value(); - return label; -} - -std::string lsCompletionItem::DisplayText() -{ - - if (detail) - { - - return label + " in " + detail.value(); - } - return label; -} - -std::string lsCompletionItem::ToString() - { - std::stringstream info; - info << "label : " << label << std::endl; - if(kind) - info << "kind : " << lsp::ToString(kind.value()) << std::endl; - else - info << "kind : no exist." << std::endl; - - if (detail) - info << "detail : " << detail.value() << std::endl; - else - info << "detail : no exist." << std::endl; - - if (documentation) - { - info << "documentation : " << std::endl; - if(documentation.value().first) - { - info << documentation.value().first.value(); - } - else if(documentation.value().second) - { - info << documentation.value().second.value().value; - } - } - else - info << "documentation : no exist." << std::endl; - - if (deprecated) - info << "deprecated : " << deprecated.value() << std::endl; - else - info << "deprecated : no exist." << std::endl; - - if (preselect) - info << "preselect : " << preselect.value() << std::endl; - else - info << "preselect : no exist." << std::endl; - - if (sortText) - info << "sortText : " << sortText.value() << std::endl; - else - info << "sortText : no exist." << std::endl; - - if (filterText) - info << "filterText : " << filterText.value() << std::endl; - else - info << "filterText : no exist." << std::endl; - - - if (insertText) - info << "insertText : " << insertText.value() << std::endl; - else - info << "insertText : no exist." << std::endl; - - - if (insertTextFormat) - info << "insertText : " << lsp::ToString(insertTextFormat.value()) << std::endl; - else - info << "insertTextFormat : no exist." << std::endl; - - if (textEdit) - info << "textEdit : " << textEdit.value().ToString() << std::endl; - else - info << "textEdit : no exist." << std::endl; - - - - return info.str(); - - } -namespace JDT -{ - namespace CodeActionKind { - - - /** - * Base kind for quickfix actions: 'quickfix' - */ - const char* QuickFix = "quickfix"; - - /** - * Base kind for refactoring actions: 'refactor' - */ - const char* Refactor = "refactor"; - - /** - * Base kind for refactoring extraction actions: 'refactor.extract' - * - * Example extract actions: - * - * - Extract method - Extract function - Extract variable - Extract interface - * from class - ... - */ - const char* RefactorExtract = "refactor.extract"; - - /** - * Base kind for refactoring inline actions: 'refactor.inline' - * - * Example inline actions: - * - * - Inline function - Inline variable - Inline constant - ... - */ - const char* RefactorInline = "refactor.inline"; - - /** - * Base kind for refactoring rewrite actions: 'refactor.rewrite' - * - * Example rewrite actions: - * - * - Convert JavaScript function to class - Add or remove parameter - - * Encapsulate field - Make method static - Move method to base class - ... - */ - const char* RefactorRewrite = "refactor.rewrite"; - - /** - * Base kind for source actions: `source` - * - * Source code actions apply to the entire file. - */ - const char* Source = "source"; - - /** - * Base kind for an organize imports source action: `source.organizeImports` - */ - const char* SourceOrganizeImports = "source.organizeImports"; - - const char* COMMAND_ID_APPLY_EDIT = "java.apply.workspaceEdit"; - - }; - - -} -Directory::Directory(const AbsolutePath& path) : path(path.path) { - lsp::EnsureEndsInSlash(this->path); -} - -bool Directory::operator==(const Directory& rhs) const { - return path == rhs.path; -} - -bool Directory::operator!=(const Directory& rhs) const { - return path != rhs.path; -} - - - - Registration Registration::Create(const std::string& method) -{ - Registration reg; - reg.method = method; - const boost::uuids::uuid a_uuid = boost::uuids::random_generator()(); - reg.id = to_string(a_uuid); - return reg; -} diff --git a/graphics/asymptote/LspCpp/src/lsp/lsp_diagnostic.cpp b/graphics/asymptote/LspCpp/src/lsp/lsp_diagnostic.cpp deleted file mode 100644 index fba0edc30c..0000000000 --- a/graphics/asymptote/LspCpp/src/lsp/lsp_diagnostic.cpp +++ /dev/null @@ -1,75 +0,0 @@ -#include "LibLsp/lsp/lsp_diagnostic.h" - -bool lsDiagnostic::operator==(const lsDiagnostic& rhs) const { - // Just check the important fields. - return range == rhs.range && message == rhs.message; -} -bool lsDiagnostic::operator!=(const lsDiagnostic& rhs) const { - return !(*this == rhs); -} - -std::string lsResponseError::ToString() -{ - std::string info = "code:"; - switch (code) - { - case lsErrorCodes::ParseError: - info += "ParseError\n"; - break; - case lsErrorCodes::InvalidRequest: - info += "InvalidRequest\n"; - break; - case lsErrorCodes::MethodNotFound: - info += "MethodNotFound\n"; - break; - case lsErrorCodes::InvalidParams: - info += "InvalidParams\n"; - break; - case lsErrorCodes::InternalError: - info += "InternalError\n"; - break; - case lsErrorCodes::serverErrorStart: - info += "serverErrorStart\n"; - break; - case lsErrorCodes::serverErrorEnd: - info += "serverErrorEnd\n"; - break; - case lsErrorCodes::ServerNotInitialized: - info += "ServerNotInitialized\n"; - break; - case lsErrorCodes::UnknownErrorCode: - info += "UnknownErrorCode\n"; - break; - // Defined by the protocol. - case lsErrorCodes::RequestCancelled: - info += "RequestCancelled\n"; - break; - default: - { - std::stringstream ss; - ss << "unknown code:" << (int32_t)code << std::endl; - info += ss.str(); - } - break; - } - info += "message:" + message; - info += "\n"; - - if(data.has_value()) - { - - info += "data:" + data.value().Data(); - info += "\n"; - } - return info; -} - -void lsResponseError::Write(Writer& visitor) { - auto& value = *this; - int code2 = static_cast<int>(this->code); - - visitor.StartObject(); - REFLECT_MEMBER2("code", code2); - REFLECT_MEMBER(message); - visitor.EndObject(); -} diff --git a/graphics/asymptote/LspCpp/src/lsp/textDocument.cpp b/graphics/asymptote/LspCpp/src/lsp/textDocument.cpp deleted file mode 100644 index c87a047d3f..0000000000 --- a/graphics/asymptote/LspCpp/src/lsp/textDocument.cpp +++ /dev/null @@ -1,349 +0,0 @@ -#include "LibLsp/lsp/textDocument/completion.h" -#include "LibLsp/lsp/textDocument/document_symbol.h" -#include "LibLsp/lsp/lsMarkedString.h" -#include "LibLsp/lsp/textDocument/hover.h" -#include "LibLsp/lsp/textDocument/prepareRename.h" -#include <LibLsp/lsp/textDocument/typeHierarchy.h> - -#include "LibLsp/lsp/textDocument/semanticHighlighting.h" -#include "LibLsp/lsp/textDocument/SemanticTokens.h" -#include "LibLsp/JsonRpc/json.h" - - -constexpr unsigned SemanticTokenEncodingSize = 5; - -std::string to_string(SemanticTokenType _type) -{ - switch (_type) { - - case ls_namespace: return "namespace"; - /** - * Represents a generic type. Acts as a fallback for types which - * can"t be mapped to a specific type like class or enum. - */ - case ls_type: return "type"; - case ls_class: return "class"; - case ls_enum: return "enum"; - case ls_interface: return "interface"; - case ls_struct: return "struct"; - case ls_typeParameter: return "typeParameter"; - case ls_parameter: return "parameter"; - case ls_variable: return "variable"; - case ls_property: return "property"; - case ls_enumMember: return "enumMember"; - case ls_event: return "event"; - case ls_function: return "function"; - case ls_method: return "method"; - case ls_macro: return "macro"; - case ls_keyword: return "keyword"; - case ls_modifier: return "modifier"; - case ls_comment: return "comment"; - case ls_string: return "string"; - case ls_number: return "number"; - case ls_regexp: return "regexp"; - case ls_operator: return "operator"; - default: - return "unknown"; - } -} - -unsigned toSemanticTokenType(std::vector<SemanticTokenType>& modifiers) -{ - unsigned encode_type = 0; - for (auto bit : modifiers) { - encode_type = encode_type | (0b00000001 << bit); - } - return encode_type; -} - -std::string to_string(TokenType_JDT _type) -{ - switch (_type) - { - case PACKAGE_JDT:return "namespace"; - case CLASS_JDT:return "class"; - case INTERFACE_JDT:return "interface"; - case ENUM_JDT:return "enum"; - case ENUM_MEMBER_JDT:return "enumMember"; - case TYPE_JDT:return "type"; - case TYPE_PARAMETER_JDT:return "typeParameter"; - case ANNOTATION_JDT:return "annotation"; - case ANNOTATION_MEMBER_JDT:return "annotationMember"; - case METHOD_JDT:return "function"; - case PROPERTY_JDT:return "property"; - case VARIABLE_JDT:return "variable"; - case PARAMETER_JDT:return "parameter"; - } - return "unknown"; -} - -std::string to_string(SemanticTokenModifier modifier) -{ - switch (modifier) { - case ls_declaration: return "declaration"; - case ls_definition: return "definition"; - case ls_readonly: return "readonly"; - case ls_static: return "static"; - case ls_deprecated: return "deprecated"; - case ls_abstract: return "abstract"; - case ls_async: return "async"; - case ls_modification: return "modification"; - case ls_documentation: return "documentation"; - case ls_defaultLibrary: return "defaultLibrary"; - default: - return "unknown"; - } -} - -unsigned toSemanticTokenModifiers(std::vector<SemanticTokenModifier>& modifiers) -{ - unsigned encodedModifiers = 0; - for (auto bit : modifiers) { - encodedModifiers = encodedModifiers | (0b00000001 << bit); - } - return encodedModifiers; -} - - -std::string toSemanticTokenType(HighlightingKind_clangD kind) { - switch (kind) { - case HighlightingKind_clangD::Variable: - case HighlightingKind_clangD::LocalVariable: - case HighlightingKind_clangD::StaticField: - return "variable"; - case HighlightingKind_clangD::Parameter: - return "parameter"; - case HighlightingKind_clangD::Function: - return "function"; - case HighlightingKind_clangD::Method: - return "method"; - case HighlightingKind_clangD::StaticMethod: - // FIXME: better method with static modifier? - return "function"; - case HighlightingKind_clangD::Field: - return "property"; - case HighlightingKind_clangD::Class: - return "class"; - case HighlightingKind_clangD::Interface: - return "interface"; - case HighlightingKind_clangD::Enum: - return "enum"; - case HighlightingKind_clangD::EnumConstant: - return "enumMember"; - case HighlightingKind_clangD::Typedef: - case HighlightingKind_clangD::Type: - return "type"; - case HighlightingKind_clangD::Unknown: - return "unknown"; // nonstandard - case HighlightingKind_clangD::Namespace: - return "namespace"; - case HighlightingKind_clangD::TemplateParameter: - return "typeParameter"; - case HighlightingKind_clangD::Concept: - return "concept"; // nonstandard - case HighlightingKind_clangD::Primitive: - return "type"; - case HighlightingKind_clangD::Macro: - return "macro"; - case HighlightingKind_clangD::InactiveCode: - return "comment"; - } - return ("unhandled HighlightingKind_clangD"); -} - -std::string toSemanticTokenModifier(HighlightingModifier_clangD modifier) { - switch (modifier) { - case HighlightingModifier_clangD::Declaration: - return "declaration"; - case HighlightingModifier_clangD::Deprecated: - return "deprecated"; - case HighlightingModifier_clangD::Readonly: - return "readonly"; - case HighlightingModifier_clangD::Static: - return "static"; - case HighlightingModifier_clangD::Deduced: - return "deduced"; // nonstandard - case HighlightingModifier_clangD::Abstract: - return "abstract"; - case HighlightingModifier_clangD::DependentName: - return "dependentName"; // nonstandard - case HighlightingModifier_clangD::DefaultLibrary: - return "defaultLibrary"; - case HighlightingModifier_clangD::FunctionScope: - return "functionScope"; // nonstandard - case HighlightingModifier_clangD::ClassScope: - return "classScope"; // nonstandard - case HighlightingModifier_clangD::FileScope: - return "fileScope"; // nonstandard - case HighlightingModifier_clangD::GlobalScope: - return "globalScope"; // nonstandard - } - return ("unhandled HighlightingModifier_clangD"); -} - - - -bool operator==(const SemanticToken& l, const SemanticToken& r) { - return std::tie(l.deltaLine, l.deltaStart, l.length, l.tokenType, - l.tokenModifiers) == std::tie(r.deltaLine, r.deltaStart, - r.length, r.tokenType, - r.tokenModifiers); -} - -std::vector<int32_t> SemanticTokens::encodeTokens(std::vector<SemanticToken>& tokens) -{ - std::vector<int32_t> result; - result.reserve(SemanticTokenEncodingSize * tokens.size()); - for (const auto& tok : tokens) - { - result.push_back(tok.deltaLine); - result.push_back(tok.deltaStart); - result.push_back(tok.length); - result.push_back(tok.tokenType); - result.push_back(tok.tokenModifiers); - } - assert(result.size() == SemanticTokenEncodingSize * tokens.size()); - return result; -} - -void Reflect(Reader& visitor, TextDocumentComplete::Either& value) -{ - if(visitor.IsArray()) - { - Reflect(visitor, value.first); - } - else - { - - Reflect(visitor, value.second); - } - -} -void Reflect(Reader& visitor, TextDocumentDocumentSymbol::Either& value) -{ - if (visitor.HasMember("location")) - { - Reflect(visitor, value.first); - } - else - { - Reflect(visitor, value.second); - } -} - -void Reflect(Reader& visitor, std::pair<optional<std::string>, optional<lsMarkedString>>& value) -{ - - if (!visitor.IsString()) - { - Reflect(visitor, value.second); - } - else - { - Reflect(visitor, value.first); - } -} - -void Reflect(Reader& visitor, std::pair<optional<std::string>, optional<MarkupContent>>& value) -{ - if (!visitor.IsString()) - { - Reflect(visitor, value.second); - } - else - { - Reflect(visitor, value.first); - } -} - void Reflect(Reader& visitor, TextDocumentHover::Either& value) -{ - JsonReader& reader = dynamic_cast<JsonReader&>(visitor); - if (reader.IsArray()) - { - Reflect(visitor, value.first); - } - else if(reader.m_->IsObject()) - { - Reflect(visitor, value.second); - } -} - - void Reflect(Reader& visitor, TextDocumentPrepareRenameResult& value) -{ - if (visitor.HasMember("placeholder")) - { - Reflect(visitor, value.second); - } - else - { - Reflect(visitor, value.first); - } -} - - namespace - RefactorProposalUtility - { - const char* APPLY_REFACTORING_COMMAND_ID = "java.action.applyRefactoringCommand"; - const char* EXTRACT_VARIABLE_ALL_OCCURRENCE_COMMAND = "extractVariableAllOccurrence"; - const char* EXTRACT_VARIABLE_COMMAND = "extractVariable"; - const char* EXTRACT_CONSTANT_COMMAND = "extractConstant"; - const char* EXTRACT_METHOD_COMMAND = "extractMethod"; - const char* EXTRACT_FIELD_COMMAND = "extractField"; - const char* CONVERT_VARIABLE_TO_FIELD_COMMAND = "convertVariableToField"; - const char* MOVE_FILE_COMMAND = "moveFile"; - const char* MOVE_INSTANCE_METHOD_COMMAND = "moveInstanceMethod"; - const char* MOVE_STATIC_MEMBER_COMMAND = "moveStaticMember"; - const char* MOVE_TYPE_COMMAND = "moveType"; - }; - namespace QuickAssistProcessor { - - const char* SPLIT_JOIN_VARIABLE_DECLARATION_ID = "org.eclipse.jdt.ls.correction.splitJoinVariableDeclaration.assist"; //$NON-NLS-1$ - const char* CONVERT_FOR_LOOP_ID = "org.eclipse.jdt.ls.correction.convertForLoop.assist"; //$NON-NLS-1$ - const char* ASSIGN_TO_LOCAL_ID = "org.eclipse.jdt.ls.correction.assignToLocal.assist"; //$NON-NLS-1$ - const char* ASSIGN_TO_FIELD_ID = "org.eclipse.jdt.ls.correction.assignToField.assist"; //$NON-NLS-1$ - const char* ASSIGN_PARAM_TO_FIELD_ID = "org.eclipse.jdt.ls.correction.assignParamToField.assist"; //$NON-NLS-1$ - const char* ASSIGN_ALL_PARAMS_TO_NEW_FIELDS_ID = "org.eclipse.jdt.ls.correction.assignAllParamsToNewFields.assist"; //$NON-NLS-1$ - const char* ADD_BLOCK_ID = "org.eclipse.jdt.ls.correction.addBlock.assist"; //$NON-NLS-1$ - const char* EXTRACT_LOCAL_ID = "org.eclipse.jdt.ls.correction.extractLocal.assist"; //$NON-NLS-1$ - const char* EXTRACT_LOCAL_NOT_REPLACE_ID = "org.eclipse.jdt.ls.correction.extractLocalNotReplaceOccurrences.assist"; //$NON-NLS-1$ - const char* EXTRACT_CONSTANT_ID = "org.eclipse.jdt.ls.correction.extractConstant.assist"; //$NON-NLS-1$ - const char* INLINE_LOCAL_ID = "org.eclipse.jdt.ls.correction.inlineLocal.assist"; //$NON-NLS-1$ - const char* CONVERT_LOCAL_TO_FIELD_ID = "org.eclipse.jdt.ls.correction.convertLocalToField.assist"; //$NON-NLS-1$ - const char* CONVERT_ANONYMOUS_TO_LOCAL_ID = "org.eclipse.jdt.ls.correction.convertAnonymousToLocal.assist"; //$NON-NLS-1$ - const char* CONVERT_TO_STRING_BUFFER_ID = "org.eclipse.jdt.ls.correction.convertToStringBuffer.assist"; //$NON-NLS-1$ - const char* CONVERT_TO_MESSAGE_FORMAT_ID = "org.eclipse.jdt.ls.correction.convertToMessageFormat.assist"; //$NON-NLS-1$; - const char* EXTRACT_METHOD_INPLACE_ID = "org.eclipse.jdt.ls.correction.extractMethodInplace.assist"; //$NON-NLS-1$; - - const char* CONVERT_ANONYMOUS_CLASS_TO_NESTED_COMMAND = "convertAnonymousClassToNestedCommand"; - }; - - void Reflect(Reader& reader, TypeHierarchyDirection& value) { - if (!reader.IsString()) - { - value = TypeHierarchyDirection::Both; - return; - } - std::string v = reader.GetString(); - if (v == "Children") - value = TypeHierarchyDirection::Both; - else if (v == "Parents") - value = TypeHierarchyDirection::Parents; - else if (v == "Both") - value = TypeHierarchyDirection::Both; - } - - - void Reflect(Writer& writer, TypeHierarchyDirection& value) { - switch (value) - { - case TypeHierarchyDirection::Children: - writer.String("Children"); - break; - case TypeHierarchyDirection::Parents: - writer.String("Parents"); - break; - case TypeHierarchyDirection::Both: - writer.String("Both"); - break; - } - } diff --git a/graphics/asymptote/LspCpp/src/lsp/utils.cpp b/graphics/asymptote/LspCpp/src/lsp/utils.cpp deleted file mode 100644 index 893cc94552..0000000000 --- a/graphics/asymptote/LspCpp/src/lsp/utils.cpp +++ /dev/null @@ -1,612 +0,0 @@ -#include "LibLsp/lsp/utils.h" - -#include <algorithm> -#include <cassert> -#include <cctype> -#include <cstring> -#include <fstream> -#include <functional> - -#include <queue> -#include <sstream> -#include <string> -#include <unordered_map> -#include <sys/stat.h> - -#include "LibLsp/lsp/lsPosition.h" -#include "utf8.h" -#ifdef _WIN32 -#include <Windows.h> -#endif - - -// DEFAULT_RESOURCE_DIRECTORY is passed with quotes for non-MSVC compilers, ie, -// foo vs "foo". -#if defined(_MSC_VER) -#define _STRINGIFY(x) #x -#define ENSURE_STRING_MACRO_ARGUMENT(x) _STRINGIFY(x) -#else -#define ENSURE_STRING_MACRO_ARGUMENT(x) x -#endif -#include <boost/filesystem/path.hpp> -#include <boost/filesystem/operations.hpp> -#include <boost/algorithm/string.hpp> -#include <boost/filesystem/directory.hpp> -namespace lsp -{ - - -// See http://stackoverflow.com/a/2072890 -bool EndsWith(std::string value, std::string ending) { - if (ending.size() > value.size()) - return false; - return std::equal(ending.rbegin(), ending.rend(), value.rbegin()); -} - -bool StartsWith(std::string value, std::string start) { - if (start.size() > value.size()) - return false; - return std::equal(start.begin(), start.end(), value.begin()); -} - -bool AnyStartsWith(const std::vector<std::string>& values, - const std::string& start) { - return std::any_of( - std::begin(values), std::end(values), - [&start](const std::string& value) { return StartsWith(value, start); }); -} - -bool StartsWithAny(const std::string& value, - const std::vector<std::string>& startings) { - return std::any_of(std::begin(startings), std::end(startings), - [&value](const std::string& starting) { - return StartsWith(value, starting); - }); -} - -bool EndsWithAny(const std::string& value, - const std::vector<std::string>& endings) { - return std::any_of( - std::begin(endings), std::end(endings), - [&value](const std::string& ending) { return EndsWith(value, ending); }); -} - -bool FindAnyPartial(const std::string& value, - const std::vector<std::string>& values) { - return std::any_of(std::begin(values), std::end(values), - [&value](const std::string& v) { - return value.find(v) != std::string::npos; - }); -} - -std::string GetDirName(std::string path) { - - ReplaceAll(path, "\\", "/"); - if (path.size() && path.back() == '/') - path.pop_back(); - size_t last_slash = path.find_last_of('/'); - if (last_slash == std::string::npos) - return "./"; - return path.substr(0, last_slash + 1); -} - -std::string GetBaseName(const std::string& path) { - size_t last_slash = path.find_last_of('/'); - if (last_slash != std::string::npos && (last_slash + 1) < path.size()) - return path.substr(last_slash + 1); - return path; -} - -std::string StripFileType(const std::string& path) { - size_t last_period = path.find_last_of('.'); - if (last_period != std::string::npos) - return path.substr(0, last_period); - return path; -} - -// See http://stackoverflow.com/a/29752943 -std::string ReplaceAll(const std::string& source, - const std::string& from, - const std::string& to) { - std::string result; - result.reserve(source.length()); // avoids a few memory allocations - - std::string::size_type last_pos = 0; - std::string::size_type find_pos; - - while (std::string::npos != (find_pos = source.find(from, last_pos))) { - result.append(source, last_pos, find_pos - last_pos); - result += to; - last_pos = find_pos + from.length(); - } - - // Care for the rest after last occurrence - result += source.substr(last_pos); - - return result; -} - -std::vector<std::string> SplitString(const std::string& str, - const std::string& delimiter) { - // http://stackoverflow.com/a/13172514 - std::vector<std::string> strings; - - std::string::size_type pos = 0; - std::string::size_type prev = 0; - while ((pos = str.find(delimiter, prev)) != std::string::npos) { - strings.emplace_back(str.substr(prev, pos - prev)); - prev = pos + 1; - } - - // To get the last substring (or only, if delimiter is not found) - strings.emplace_back(str.substr(prev)); - - return strings; -} - -void EnsureEndsInSlash(std::string& path) { - if (path.empty() || path[path.size() - 1] != '/') - path += '/'; -} - -std::string EscapeFileName(std::string path) { - if (path.size() && path.back() == '/') - path.pop_back(); - std::replace(path.begin(), path.end(), '\\', '@'); - std::replace(path.begin(), path.end(), '/', '@'); - std::replace(path.begin(), path.end(), ':', '@'); - return path; -} - -// http://stackoverflow.com/a/6089413 -std::istream& SafeGetline(std::istream& is, std::string& t) { - t.clear(); - - // The characters in the stream are read one-by-one using a std::streambuf. - // That is faster than reading them one-by-one using the std::istream. Code - // that uses streambuf this way must be guarded by a sentry object. The sentry - // object performs various tasks, such as thread synchronization and updating - // the stream state. - - std::istream::sentry se(is, true); - std::streambuf* sb = is.rdbuf(); - - for (;;) { - int c = sb->sbumpc(); - if (c == EOF) { - // Also handle the case when the last line has no line ending - if (t.empty()) - is.setstate(std::ios::eofbit); - return is; - } - - t += (char)c; - - if (c == '\n') - return is; - } -} - -bool FileExists(const std::string& filename) { - std::ifstream cache(filename); - return cache.is_open(); -} - -optional<std::string> ReadContent(const AbsolutePath& filename) { - - std::ifstream cache; - cache.open(filename.path); - - try { - return std::string(std::istreambuf_iterator<char>(cache), - std::istreambuf_iterator<char>()); - } catch (std::ios_base::failure&) { - return {}; - } -} - -std::vector<std::string> ReadLinesWithEnding(const AbsolutePath& filename) { - std::vector<std::string> result; - - std::ifstream input(filename.path); - for (std::string line; SafeGetline(input, line);) - result.emplace_back(line); - - return result; -} - -bool WriteToFile(const std::string& filename, const std::string& content) { - std::ofstream file(filename, - std::ios::out | std::ios::trunc | std::ios::binary); - if (!file.good()) { - - return false; - } - - file << content; - return true; -} - - -std::string FormatMicroseconds(long long microseconds) { - long long milliseconds = microseconds / 1000; - long long remaining = microseconds - milliseconds; - - // Only show two digits after the dot. - while (remaining >= 100) - remaining /= 10; - - return std::to_string(milliseconds) + "." + std::to_string(remaining) + "ms"; -} - - - -std::string UpdateToRnNewlines(std::string output) { - size_t idx = 0; - while (true) { - idx = output.find('\n', idx); - - // No more matches. - if (idx == std::string::npos) - break; - - // Skip an existing "\r\n" match. - if (idx > 0 && output[idx - 1] == '\r') { - ++idx; - continue; - } - - // Replace "\n" with "\r|n". - output.replace(output.begin() + idx, output.begin() + idx + 1, "\r\n"); - } - - return output; -} - - - -bool IsAbsolutePath(const std::string& path) { - return IsUnixAbsolutePath(path) || IsWindowsAbsolutePath(path); -} - -bool IsUnixAbsolutePath(const std::string& path) { - return !path.empty() && path[0] == '/'; -} - -bool IsWindowsAbsolutePath(const std::string& path) { - auto is_drive_letter = [](char c) { - return (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z'); - }; - - return path.size() > 3 && path[1] == ':' && - (path[2] == '/' || path[2] == '\\') && is_drive_letter(path[0]); -} - -bool IsDirectory(const std::string& path) { - struct stat path_stat; - - if (stat(path.c_str(), &path_stat) != 0) { - perror("cannot access path"); - return false; - } - - return path_stat.st_mode & S_IFDIR; -} - - std::string ws2s(std::wstring const& wstr) { - if(sizeof(wchar_t) == 2){ - std::string narrow; - utf8::utf16to8(wstr.begin(), wstr.end(), std::back_inserter(narrow)); - return narrow; - }else{ - std::string narrow; - utf8::utf32to8(wstr.begin(), wstr.end(), std::back_inserter(narrow)); - return narrow; - } - - } - std::wstring s2ws(const std::string& str) { - std::wstring wide; - if(sizeof(wchar_t) == 2){ - utf8::utf8to16(str.begin(), str.end(), std::back_inserter(wide)); - return wide; - }else{ - utf8::utf8to32(str.begin(), str.end(), std::back_inserter(wide)); - return wide; - } - } - -#ifdef _WIN32 - -#else -// Returns the canonicalized absolute pathname, without expanding symbolic -// links. This is a variant of realpath(2), C++ rewrite of -// https://github.com/freebsd/freebsd/blob/master/lib/libc/stdlib/realpath.c -AbsolutePath RealPathNotExpandSymlink(std::string path, - bool ensure_exists) { - if (path.empty()) { - errno = EINVAL; - return {}; - } - if (path[0] == '\0') { - errno = ENOENT; - return {}; - } - - // Do not use PATH_MAX because it is tricky on Linux. - // See https://eklitzke.org/path-max-is-tricky - char tmp[1024]; - std::string resolved; - size_t i = 0; - struct stat sb; - if (path[0] == '/') { - resolved = "/"; - i = 1; - } - else { - if (!getcwd(tmp, sizeof tmp) && ensure_exists) - return {}; - resolved = tmp; - } - - while (i < path.size()) { - auto j = path.find('/', i); - if (j == std::string::npos) - j = path.size(); - auto next_token = path.substr(i, j - i); - i = j + 1; - if (resolved.back() != '/') - resolved += '/'; - if (next_token.empty() || next_token == ".") { - // Handle consequential slashes and "." - continue; - } - else if (next_token == "..") { - // Strip the last path component except when it is single "/" - if (resolved.size() > 1) - resolved.resize(resolved.rfind('/', resolved.size() - 2) + 1); - continue; - } - // Append the next path component. - // Here we differ from realpath(3), we use stat(2) instead of - // lstat(2) because we do not want to resolve symlinks. - resolved += next_token; - if (stat(resolved.c_str(), &sb) != 0 && ensure_exists) - return {}; - if (!S_ISDIR(sb.st_mode) && j < path.size() && ensure_exists) { - errno = ENOTDIR; - return {}; - } - } - - // Remove trailing slash except when a single "/". - if (resolved.size() > 1 && resolved.back() == '/') - resolved.pop_back(); - return AbsolutePath(resolved, true /*validate*/); -} -#endif - - -AbsolutePath NormalizePath(const std::string& path0, - bool ensure_exists , - bool force_lower_on_windows) { -#ifdef _WIN32 - - std::wstring path = lsp::s2ws(path0); - - wchar_t buffer[MAX_PATH] = (L""); - - // Normalize the path name, ie, resolve `..`. - unsigned long len = GetFullPathNameW(path.c_str(), MAX_PATH, buffer, nullptr); - if (!len) - return {}; - path = std::wstring(buffer, len); - - // Get the actual casing of the path, ie, if the file on disk is `C:\FooBar` - // and this function is called with `c:\fooBar` this will return `c:\FooBar`. - // (drive casing is lowercase). - if (ensure_exists) { - len = GetLongPathNameW(path.c_str(), buffer, MAX_PATH); - if (!len) - return {}; - path = std::wstring(buffer, len); - } - - // Empty paths have no meaning. - if (path.empty()) - return {}; - - // We may need to normalize the drive name to upper-case; at the moment - // vscode sends lower-case path names. - /* - path[0] = toupper(path[0]); - */ - // Make the path all lower-case, since windows is case-insensitive. - if (force_lower_on_windows) { - for (size_t i = 0; i < path.size(); ++i) - path[i] = (wchar_t)tolower(path[i]); - } - - // cquery assumes forward-slashes. - std::replace(path.begin(), path.end(), '\\', '/'); - - - return AbsolutePath(lsp::ws2s(path), false /*validate*/); -#else - - return RealPathNotExpandSymlink(path0, ensure_exists); - -#endif - - -} - -// VSCode (UTF-16) disagrees with Emacs lsp-mode (UTF-8) on how to represent -// text documents. -// We use a UTF-8 iterator to approximate UTF-16 in the specification (weird). -// This is good enough and fails only for UTF-16 surrogate pairs. -int GetOffsetForPosition(lsPosition position, const std::string& content) { - size_t i = 0; - // Iterate lines until we have found the correct line. - while (position.line > 0 && i < content.size()) { - if (content[i] == '\n') - position.line--; - i++; - } - // Iterate characters on the target line. - while (position.character > 0 && i < content.size()) { - if (uint8_t(content[i++]) >= 128) { - // Skip 0b10xxxxxx - while (i < content.size() && uint8_t(content[i]) >= 128 && - uint8_t(content[i]) < 192) - i++; - } - position.character--; - } - return int(i); -} - - -lsPosition GetPositionForOffset(size_t offset,const std::string& content) { - lsPosition result; - for (size_t i = 0; i < offset && i < content.length(); ++i) { - if (content[i] == '\n') { - result.line++; - result.character = 0; - } - else { - result.character++; - } - } - return result; -} - -lsPosition CharPos(const std::string& search, - char character, - int character_offset) { - lsPosition result; - size_t index = 0; - while (index < search.size()) { - char c = search[index]; - if (c == character) - break; - if (c == '\n') { - result.line += 1; - result.character = 0; - } - else { - result.character += 1; - } - ++index; - } - assert(index < search.size()); - result.character += character_offset; - return result; -} - -void scanDirsUseRecursive(const std::wstring& rootPath, std::vector<std::wstring>& ret) -{ - namespace fs = boost::filesystem; - fs::path fullpath(rootPath); - if (!fs::exists(fullpath)) { return; } - fs::recursive_directory_iterator end_iter; - for (fs::recursive_directory_iterator iter(fullpath); iter != end_iter; iter++) { - try { - if (fs::is_directory(*iter)) { - ret.push_back(iter->path().wstring()); - } - } - catch (const std::exception& ex) { - continue; - } - } -} - -void scanDirsNoRecursive(const std::wstring& rootPath, std::vector<std::wstring>& ret) -{ - namespace fs = boost::filesystem; - boost::filesystem::path myPath(rootPath); - if (!fs::exists(rootPath)) { return; } - boost::filesystem::directory_iterator endIter; - for (boost::filesystem::directory_iterator iter(myPath); iter != endIter; iter++) { - if (boost::filesystem::is_directory(*iter)) { - ret.push_back(iter->path().wstring()); - } - } -} - -void scanFilesUseRecursive( - const std::wstring& rootPath, - std::vector<std::wstring>& ret, - std::wstring suf) { - namespace fs = boost::filesystem; - boost::to_lower(suf); - - fs::path fullpath(rootPath); - if (!fs::exists(fullpath)) { return; } - fs::recursive_directory_iterator end_iter; - for (fs::recursive_directory_iterator iter(fullpath); iter != end_iter; iter++) { - try { - if (!fs::is_directory(*iter) && fs::is_regular_file(*iter)) { - auto temp_path = iter->path().wstring(); - auto size = suf.size(); - if (!size) - { - ret.push_back(std::move(temp_path)); - } - else - { - - if (temp_path.size() < size) continue; - auto suf_temp = temp_path.substr(temp_path.size() - size); - boost::to_lower(suf_temp); - if (suf_temp == suf) - { - ret.push_back(std::move(temp_path)); - } - } - } - } - catch (const std::exception&) { - continue; - } - } -} - -void scanFileNamesUseRecursive(const std::wstring& rootPath, std::vector<std::wstring>& ret, - std::wstring strSuf) -{ - scanFilesUseRecursive(rootPath, ret, strSuf); - std::vector<std::wstring> names; - for (auto& it : ret) - { - if (it.size() >= rootPath.size()) - { - names.push_back(it.substr(rootPath.size())); - } - } - ret.swap(names); -} - -void scanFileNamesUseRecursive(const std::string& rootPath, std::vector<std::string>& ret, std::string strSuf) -{ - std::vector<std::wstring> out; - scanFileNamesUseRecursive(s2ws(rootPath), out, s2ws(strSuf)); - for (auto& it : out) - { - ret.push_back(ws2s(it)); - } -} - -void scanFilesUseRecursive(const std::string& rootPath, std::vector<std::string>& ret, std::string strSuf) -{ - std::vector<std::wstring> out; - scanFilesUseRecursive(s2ws(rootPath), out, s2ws(strSuf)); - for (auto& it : out) - { - ret.push_back(ws2s(it)); - } -} - - -} diff --git a/graphics/asymptote/LspCpp/src/lsp/working_files.cpp b/graphics/asymptote/LspCpp/src/lsp/working_files.cpp deleted file mode 100644 index 4eb4b29053..0000000000 --- a/graphics/asymptote/LspCpp/src/lsp/working_files.cpp +++ /dev/null @@ -1,186 +0,0 @@ -#include "LibLsp/lsp/working_files.h" -#include <algorithm> -#include <climits> -#include <numeric> -#include "LibLsp/lsp/utils.h" -#include <memory> -#include "LibLsp/lsp/AbsolutePath.h" -using namespace lsp; -struct WorkingFilesData -{ - std::map<AbsolutePath, std::shared_ptr<WorkingFile> > files; - std::mutex files_mutex; // Protects |d_ptr->files|. -}; - -WorkingFile::WorkingFile(WorkingFiles& _parent, const AbsolutePath& filename, - const std::string& buffer_content) - : filename(filename), directory(filename), parent(_parent), counter(0), buffer_content(buffer_content) -{ - directory = Directory(GetDirName(filename.path)); -} - -WorkingFile::WorkingFile(WorkingFiles& _parent, const AbsolutePath& filename, - std::string&& buffer_content) - : filename(filename), directory(filename), parent(_parent), counter(0), buffer_content(buffer_content) -{ - directory = Directory(GetDirName(filename.path)); -} - -WorkingFiles::WorkingFiles():d_ptr(new WorkingFilesData()) -{ -} - -WorkingFiles::~WorkingFiles() -{ - delete d_ptr; - -} - - - -void WorkingFiles::CloseFilesInDirectory(const std::vector<Directory>& directories) -{ - std::lock_guard<std::mutex> lock(d_ptr->files_mutex); - std::vector<AbsolutePath> files_to_be_delete; - - for(auto& it : d_ptr->files) - { - for (auto& dir : directories) - { - if (it.second->directory == dir) { - files_to_be_delete.emplace_back(it.first); - } - } - } - - for(auto& it : files_to_be_delete) - { - d_ptr->files.erase(it); - } -} - - - - -std::shared_ptr<WorkingFile> WorkingFiles::GetFileByFilename(const AbsolutePath& filename) { - std::lock_guard<std::mutex> lock(d_ptr->files_mutex); - return GetFileByFilenameNoLock(filename); -} - -std::shared_ptr<WorkingFile> WorkingFiles::GetFileByFilenameNoLock( - const AbsolutePath& filename) { - const auto findIt = d_ptr->files.find(filename); - if ( findIt != d_ptr->files.end()) - { - return findIt->second; - } - return nullptr; -} - - - -std::shared_ptr<WorkingFile> WorkingFiles::OnOpen( lsTextDocumentItem& open) { - std::lock_guard<std::mutex> lock(d_ptr->files_mutex); - - AbsolutePath filename = open.uri.GetAbsolutePath(); - - // The file may already be open. - if (auto file = GetFileByFilenameNoLock(filename)) { - file->version = open.version; - file->buffer_content.swap(open.text); - - return file; - } - - const auto& it = d_ptr->files.insert({ filename,std::make_shared<WorkingFile>(*this,filename, std::move(open.text)) }); - return it.first->second; -} - - -std::shared_ptr<WorkingFile> WorkingFiles::OnChange(const lsTextDocumentDidChangeParams& change) { - std::lock_guard<std::mutex> lock(d_ptr->files_mutex); - - AbsolutePath filename = change.textDocument.uri.GetAbsolutePath(); - auto file = GetFileByFilenameNoLock(filename); - if (!file) { - return {}; - } - - if (change.textDocument.version) - file->version = *change.textDocument.version; - file->counter.fetch_add(1, std::memory_order_relaxed); - for (const lsTextDocumentContentChangeEvent& diff : change.contentChanges) { - // Per the spec replace everything if the rangeLength and range are not set. - // See https://github.com/Microsoft/language-server-protocol/issues/9. - if (!diff.range) { - file->buffer_content = diff.text; - - } else { - int start_offset = - GetOffsetForPosition(diff.range->start, file->buffer_content); - // Ignore TextDocumentContentChangeEvent.rangeLength which causes trouble - // when UTF-16 surrogate pairs are used. - int end_offset = - GetOffsetForPosition(diff.range->end, file->buffer_content); - file->buffer_content.replace(file->buffer_content.begin() + start_offset, - file->buffer_content.begin() + end_offset, - diff.text); - - } - } - return file; -} - -bool WorkingFiles::OnClose(const lsTextDocumentIdentifier& close) { - std::lock_guard<std::mutex> lock(d_ptr->files_mutex); - - AbsolutePath filename = close.uri.GetAbsolutePath(); - const auto findIt = d_ptr->files.find(filename); - if( findIt != d_ptr->files.end()) - { - d_ptr->files.erase(findIt); - return true; - } - return false; -} - -std::shared_ptr<WorkingFile> WorkingFiles::OnSave(const lsTextDocumentIdentifier& _save) -{ - std::lock_guard<std::mutex> lock(d_ptr->files_mutex); - - AbsolutePath filename = _save.uri.GetAbsolutePath(); - const auto findIt = d_ptr->files.find(filename); - if (findIt != d_ptr->files.end()) - { - std::shared_ptr<WorkingFile>& file = findIt->second; - lsp::WriteToFile(file->filename, file->GetContentNoLock()); - return findIt->second; - } - return {}; - -} - -bool WorkingFiles::GetFileBufferContent(std::shared_ptr<WorkingFile>&file, std::string& out) -{ - std::lock_guard<std::mutex> lock(d_ptr->files_mutex); - if (file) - { - out = file->buffer_content; - return true; - } - return false; -} -bool WorkingFiles::GetFileBufferContent(std::shared_ptr<WorkingFile>& file, std::wstring& out) -{ - std::lock_guard<std::mutex> lock(d_ptr->files_mutex); - if (file) - { - out = lsp::s2ws(file->buffer_content); - return true; - } - return false; -} -void WorkingFiles::Clear() { - std::lock_guard<std::mutex> lock(d_ptr->files_mutex); - d_ptr->files.clear(); -} |