diff options
Diffstat (limited to 'graphics/asymptote/LspCpp/src/lsp')
-rw-r--r-- | graphics/asymptote/LspCpp/src/lsp/Markup.cpp | 1779 | ||||
-rw-r--r-- | graphics/asymptote/LspCpp/src/lsp/ParentProcessWatcher.cpp | 140 | ||||
-rw-r--r-- | graphics/asymptote/LspCpp/src/lsp/ProtocolJsonHandler.cpp | 1095 | ||||
-rw-r--r-- | graphics/asymptote/LspCpp/src/lsp/initialize.cpp | 72 | ||||
-rw-r--r-- | graphics/asymptote/LspCpp/src/lsp/lsp.cpp | 1469 | ||||
-rw-r--r-- | graphics/asymptote/LspCpp/src/lsp/lsp_diagnostic.cpp | 127 | ||||
-rw-r--r-- | graphics/asymptote/LspCpp/src/lsp/textDocument.cpp | 610 | ||||
-rw-r--r-- | graphics/asymptote/LspCpp/src/lsp/utils.cpp | 955 | ||||
-rw-r--r-- | graphics/asymptote/LspCpp/src/lsp/working_files.cpp | 183 |
9 files changed, 3438 insertions, 2992 deletions
diff --git a/graphics/asymptote/LspCpp/src/lsp/Markup.cpp b/graphics/asymptote/LspCpp/src/lsp/Markup.cpp index f22baac95d..6907df4f76 100644 --- a/graphics/asymptote/LspCpp/src/lsp/Markup.cpp +++ b/graphics/asymptote/LspCpp/src/lsp/Markup.cpp @@ -16,443 +16,572 @@ #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; +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) +{ + char const HexChar = LowerCase ? 'a' : 'A'; + auto const castedX = static_cast<char>(X); + return X < 10 ? '0' + castedX : HexChar + castedX - 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(char const* 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(std::vector<uint8_t> const& Input) +{ + return std::string_ref(Input.begin(), Input.end()); +} - /// 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; +/// Construct a string ref from an array ref of unsigned chars. +inline std::vector<uint8_t> arrayRefFromStringRef(std::string_ref const& 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; } - }; - constexpr HexTable Table; - return Table.LUT[static_cast<unsigned char>(C)]; - } + // 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 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 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 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 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 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) +/// Checks whether all characters in S are ASCII. +inline bool isASCII(std::string_ref S) +{ + for (char C : S) + { + if (!isASCII(C)) { - if(!isASCII(C))return true; + return true; } - 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 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'; +} - /// 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 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); - /// 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; + if (X == 0) + { + *--BufPtr = '0'; } - inline std::string utohexstr(uint64_t X, bool LowerCase = false) { - char Buffer[17]; - char* BufPtr = std::end(Buffer); + while (X) + { + unsigned char Mod = static_cast<unsigned char>(X) & 15; + *--BufPtr = hexdigit(Mod, LowerCase); + X >>= 4; + } - if (X == 0) *--BufPtr = '0'; + return std::string(BufPtr, std::end(Buffer)); +} - while (X) { - unsigned char Mod = static_cast<unsigned char>(X) & 15; - *--BufPtr = hexdigit(Mod, LowerCase); - X >>= 4; - } +/// 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 char const* const LUT = "0123456789ABCDEF"; + uint8_t const Offset = LowerCase ? 32 : 0; + size_t Length = Input.size(); - return std::string(BufPtr, std::end(Buffer)); + std::string Output; + Output.reserve(2 * Length); + for (size_t i = 0; i < Length; ++i) + { + unsigned char const c = Input[i]; + Output.push_back(LUT[c >> 4] | Offset); + Output.push_back(LUT[c & 15] | Offset); } + return Output; +} - /// 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(); +inline std::string toHex(std::vector<uint8_t> Input, bool LowerCase = false) +{ + return toHex(toStringRef(Input), LowerCase); +} - 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; +/// 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; } - inline std::string toHex(std::vector<uint8_t> Input, bool LowerCase = false) { - return toHex(toStringRef(Input), LowerCase); - } + Hex = static_cast<uint8_t>((U1 << 4) | U2); + return true; +} - /// 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; +/// 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; +} - Hex = static_cast<uint8_t>((U1 << 4) | U2); +/// 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; } - /// 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) { + Output.reserve((Input.size() + 1) / 2); + if (Input.size() % 2 == 1) + { 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(); + if (!tryGetHexFromNibbles('0', Input.front(), Hex)) + { + return false; } - 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(); + } - Output.push_back(Hex); - Input = Input.drop_front(2); + assert(Input.size() % 2 == 0); + while (!Input.empty()) + { + uint8_t Hex = 0; + if (!tryGetHexFromNibbles(Input[0], Input[1], Hex)) + { + return false; } - 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; + 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); - 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)); + if (X == 0) + { + *--BufPtr = '0'; // Handle special case... } - 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)); + while (X) + { + *--BufPtr = '0' + char(X % 10); + X /= 10; } - /// 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"); - + 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)); + } +} - /// 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"; +/// 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: - switch (Val % 10) { - case 1: return "st"; - case 2: return "nd"; - case 3: return "rd"; - default: return "th"; - } + return "th"; } } +} - namespace detail { +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; + 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); - 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; } - 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; + 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); - while (++Begin != End) { - S += Separator; - S += (*Begin); - } - assert(PrevCapacity == S.capacity() && "String grew during building"); - return S; } + 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> + 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 Arg> + inline void join_items_impl(std::string& Result, Sep Separator, Arg const& 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)...); - } + template<typename Sep, typename Arg1, typename... Args> + inline void join_items_impl(std::string& Result, Sep Separator, Arg1 const& 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(char const* S) + { + return S ? ::strlen(S) : 0; + } - 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(T const& Str) + { + return Str.size(); + } - template <typename T> inline size_t join_one_item_size(const T& Str) { - return Str.size(); - } + inline size_t join_items_size() + { + return 0; + } - 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)...); + } - 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 - } // 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)...); +/// 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; } - /// 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; + 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{ +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. +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. @@ -463,480 +592,556 @@ bool looksLikeTag(std::string_ref& Contents) { // 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) +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 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; - } + 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; +std::string_ref renderText(std::string_ref const& 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) + "`"; +std::string_ref renderInlineBlock(std::string_ref const& 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") +std::string_ref getMarkerForCodeBlock(std::string_ref const& Input) { - boost::split(OutFragments, Source, boost::is_any_of(Delimiters)); + // 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( + std::string const& 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) +std::string_ref canonicalizeSpaces(std::string_ref const& 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(), [](Block const* C) { return C->isRuler(); }), Children.end() + ); + + bool LastBlockWasRuler = true; + for (auto const& 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](char const& C) { - temp[i]=(children[i].get()); + 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( + std::vector<std::unique_ptr<Block>> const& 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 { +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; } + 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 { +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 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"; - } + 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); - } + 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)) {} + 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; + 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 { +std::string_ref indentLines(std::string_ref const& 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); - } + 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; + 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, std::string_ref const& 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(std::string_ref const& 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(std::string_ref const& 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=(Document const& Other) +{ + Children.clear(); + for (auto const& 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>()); +} - 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()); - } - }; +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()); +} +}; // namespace lsp diff --git a/graphics/asymptote/LspCpp/src/lsp/ParentProcessWatcher.cpp b/graphics/asymptote/LspCpp/src/lsp/ParentProcessWatcher.cpp index c698a3157e..ee4147b76b 100644 --- a/graphics/asymptote/LspCpp/src/lsp/ParentProcessWatcher.cpp +++ b/graphics/asymptote/LspCpp/src/lsp/ParentProcessWatcher.cpp @@ -3,7 +3,7 @@ #include <boost/process.hpp> #ifdef _WIN32 -#include <boost/process/windows.hpp> +#include <boost/process/v1/windows.hpp> #endif #include <boost/filesystem.hpp> @@ -13,95 +13,103 @@ #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; + 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; + int const _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) - { + ParentProcessWatcherData(lsp::Log& log, int _pid, std::function<void()> const&& 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) + "\""; + command = + "cmd /c \"tasklist /FI \"PID eq " + std::to_string(pid) + "\" | findstr " + std::to_string(pid) + "\""; #else - command = "ps -p " + std::to_string(pid); + 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>(); + 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, + // 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, + 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) - { + bp::std_out > *read_from_service, bp::std_in < *write_to_service, + bp::on_exit( + [self](int exit_code, std::error_code const&) + { + // 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 + std::thread( + [=]() { - 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(); - }); + 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) + ); + } - })); - if (ec) - { - // fail - _log.log(lsp::Log::Level::SEVERE, "Start parent process watcher failed."); + 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)) +ParentProcessWatcher::ParentProcessWatcher( + lsp::Log& log, int pid, std::function<void()> const&& callback, uint32_t poll_delay_secs +) + : d_ptr(new ParentProcessWatcherData(log, pid, std::move(callback), poll_delay_secs)) { - d_ptr->run(); + d_ptr->run(); } ParentProcessWatcher::~ParentProcessWatcher() { - if (d_ptr->timer) - d_ptr->timer->Stop(); + 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 index c860b555af..123a580c5c 100644 --- a/graphics/asymptote/LspCpp/src/lsp/ProtocolJsonHandler.cpp +++ b/graphics/asymptote/LspCpp/src/lsp/ProtocolJsonHandler.cpp @@ -5,7 +5,6 @@ #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" @@ -70,647 +69,639 @@ #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); - - }; - + 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) + handler.method2response[java_classFileContents::request::kMethodInfo] = [](Reader& visitor) + { + if (visitor.HasMember("error")) { - if (visitor.HasMember("error")) - return Rsp_Error::ReflectReader(visitor); + return Rsp_Error::ReflectReader(visitor); + } - return java_classFileContents::response::ReflectReader(visitor); - }; - handler.method2response[java_buildWorkspace::request::kMethodInfo] = [](Reader& visitor) + return java_classFileContents::response::ReflectReader(visitor); + }; + handler.method2response[java_buildWorkspace::request::kMethodInfo] = [](Reader& visitor) + { + if (visitor.HasMember("error")) { - if (visitor.HasMember("error")) - return Rsp_Error::ReflectReader(visitor); + return Rsp_Error::ReflectReader(visitor); + } - return java_buildWorkspace::response::ReflectReader(visitor); - }; - handler.method2response[java_listOverridableMethods::request::kMethodInfo] = [](Reader& visitor) + return java_buildWorkspace::response::ReflectReader(visitor); + }; + handler.method2response[java_listOverridableMethods::request::kMethodInfo] = [](Reader& visitor) + { + if (visitor.HasMember("error")) { - if (visitor.HasMember("error")) - return Rsp_Error::ReflectReader(visitor); + return Rsp_Error::ReflectReader(visitor); + } - return java_listOverridableMethods::response::ReflectReader(visitor); - }; - handler.method2response[java_listOverridableMethods::request::kMethodInfo] = [](Reader& visitor) + return java_listOverridableMethods::response::ReflectReader(visitor); + }; + handler.method2response[java_listOverridableMethods::request::kMethodInfo] = [](Reader& visitor) + { + if (visitor.HasMember("error")) { - if (visitor.HasMember("error")) - return Rsp_Error::ReflectReader(visitor); + return Rsp_Error::ReflectReader(visitor); + } - return java_listOverridableMethods::response::ReflectReader(visitor); - }; + return java_listOverridableMethods::response::ReflectReader(visitor); + }; - handler.method2response[java_checkHashCodeEqualsStatus::request::kMethodInfo] = [](Reader& visitor) + handler.method2response[java_checkHashCodeEqualsStatus::request::kMethodInfo] = [](Reader& visitor) + { + if (visitor.HasMember("error")) { - if (visitor.HasMember("error")) - return Rsp_Error::ReflectReader(visitor); - - return java_checkHashCodeEqualsStatus::response::ReflectReader(visitor); - }; + return Rsp_Error::ReflectReader(visitor); + } + return java_checkHashCodeEqualsStatus::response::ReflectReader(visitor); + }; - handler.method2response[java_addOverridableMethods::request::kMethodInfo] = [](Reader& visitor) + handler.method2response[java_addOverridableMethods::request::kMethodInfo] = [](Reader& visitor) + { + if (visitor.HasMember("error")) { - if (visitor.HasMember("error")) - return Rsp_Error::ReflectReader(visitor); + return Rsp_Error::ReflectReader(visitor); + } - return java_addOverridableMethods::response::ReflectReader(visitor); - }; + return java_addOverridableMethods::response::ReflectReader(visitor); + }; - handler.method2response[java_checkConstructorsStatus::request::kMethodInfo] = [](Reader& visitor) + handler.method2response[java_checkConstructorsStatus::request::kMethodInfo] = [](Reader& visitor) + { + if (visitor.HasMember("error")) { - if (visitor.HasMember("error")) - return Rsp_Error::ReflectReader(visitor); + return Rsp_Error::ReflectReader(visitor); + } - return java_checkConstructorsStatus::response::ReflectReader(visitor); - }; + return java_checkConstructorsStatus::response::ReflectReader(visitor); + }; - - handler.method2response[java_checkDelegateMethodsStatus::request::kMethodInfo] = [](Reader& visitor) + handler.method2response[java_checkDelegateMethodsStatus::request::kMethodInfo] = [](Reader& visitor) + { + if (visitor.HasMember("error")) { - if (visitor.HasMember("error")) - return Rsp_Error::ReflectReader(visitor); + return Rsp_Error::ReflectReader(visitor); + } - return java_checkDelegateMethodsStatus::response::ReflectReader(visitor); - }; - handler.method2response[java_checkToStringStatus::request::kMethodInfo] = [](Reader& visitor) + return java_checkDelegateMethodsStatus::response::ReflectReader(visitor); + }; + handler.method2response[java_checkToStringStatus::request::kMethodInfo] = [](Reader& visitor) + { + if (visitor.HasMember("error")) { - if (visitor.HasMember("error")) - return Rsp_Error::ReflectReader(visitor); - - return java_checkToStringStatus::response::ReflectReader(visitor); - }; + return Rsp_Error::ReflectReader(visitor); + } + return java_checkToStringStatus::response::ReflectReader(visitor); + }; - handler.method2response[java_generateAccessors::request::kMethodInfo] = [](Reader& visitor) + handler.method2response[java_generateAccessors::request::kMethodInfo] = [](Reader& visitor) + { + if (visitor.HasMember("error")) { - if (visitor.HasMember("error")) - return Rsp_Error::ReflectReader(visitor); + return Rsp_Error::ReflectReader(visitor); + } - return java_generateAccessors::response::ReflectReader(visitor); - }; - handler.method2response[java_generateConstructors::request::kMethodInfo] = [](Reader& visitor) + return java_generateAccessors::response::ReflectReader(visitor); + }; + handler.method2response[java_generateConstructors::request::kMethodInfo] = [](Reader& visitor) + { + if (visitor.HasMember("error")) { - if (visitor.HasMember("error")) - return Rsp_Error::ReflectReader(visitor); + return Rsp_Error::ReflectReader(visitor); + } - return java_generateConstructors::response::ReflectReader(visitor); - }; - handler.method2response[java_generateDelegateMethods::request::kMethodInfo] = [](Reader& visitor) + return java_generateConstructors::response::ReflectReader(visitor); + }; + handler.method2response[java_generateDelegateMethods::request::kMethodInfo] = [](Reader& visitor) + { + if (visitor.HasMember("error")) { - if (visitor.HasMember("error")) - return Rsp_Error::ReflectReader(visitor); + return Rsp_Error::ReflectReader(visitor); + } - return java_generateDelegateMethods::response::ReflectReader(visitor); - }; + return java_generateDelegateMethods::response::ReflectReader(visitor); + }; - handler.method2response[java_generateHashCodeEquals::request::kMethodInfo] = [](Reader& visitor) + handler.method2response[java_generateHashCodeEquals::request::kMethodInfo] = [](Reader& visitor) + { + if (visitor.HasMember("error")) { - if (visitor.HasMember("error")) - return Rsp_Error::ReflectReader(visitor); + return Rsp_Error::ReflectReader(visitor); + } - return java_generateHashCodeEquals::response::ReflectReader(visitor); - }; - handler.method2response[java_generateToString::request::kMethodInfo] = [](Reader& visitor) + return java_generateHashCodeEquals::response::ReflectReader(visitor); + }; + handler.method2response[java_generateToString::request::kMethodInfo] = [](Reader& visitor) + { + if (visitor.HasMember("error")) { - if (visitor.HasMember("error")) - return Rsp_Error::ReflectReader(visitor); + return Rsp_Error::ReflectReader(visitor); + } - return java_generateToString::response::ReflectReader(visitor); - }; + return java_generateToString::response::ReflectReader(visitor); + }; - handler.method2response[java_generateToString::request::kMethodInfo] = [](Reader& visitor) + handler.method2response[java_generateToString::request::kMethodInfo] = [](Reader& visitor) + { + if (visitor.HasMember("error")) { - if (visitor.HasMember("error")) - return Rsp_Error::ReflectReader(visitor); + return Rsp_Error::ReflectReader(visitor); + } - return java_generateToString::response::ReflectReader(visitor); - }; + return java_generateToString::response::ReflectReader(visitor); + }; - handler.method2response[java_getMoveDestinations::request::kMethodInfo] = [](Reader& visitor) + handler.method2response[java_getMoveDestinations::request::kMethodInfo] = [](Reader& visitor) + { + if (visitor.HasMember("error")) { - if (visitor.HasMember("error")) - return Rsp_Error::ReflectReader(visitor); + return Rsp_Error::ReflectReader(visitor); + } - return java_getMoveDestinations::response::ReflectReader(visitor); - }; + return java_getMoveDestinations::response::ReflectReader(visitor); + }; - handler.method2response[java_getRefactorEdit::request::kMethodInfo] = [](Reader& visitor) + handler.method2response[java_getRefactorEdit::request::kMethodInfo] = [](Reader& visitor) + { + if (visitor.HasMember("error")) { - if (visitor.HasMember("error")) - return Rsp_Error::ReflectReader(visitor); + return Rsp_Error::ReflectReader(visitor); + } - return java_getRefactorEdit::response::ReflectReader(visitor); - }; + return java_getRefactorEdit::response::ReflectReader(visitor); + }; - handler.method2response[java_move::request::kMethodInfo] = [](Reader& visitor) + handler.method2response[java_move::request::kMethodInfo] = [](Reader& visitor) + { + if (visitor.HasMember("error")) { - if (visitor.HasMember("error")) - return Rsp_Error::ReflectReader(visitor); + return Rsp_Error::ReflectReader(visitor); + } - return java_move::response ::ReflectReader(visitor); - }; + return java_move::response ::ReflectReader(visitor); + }; - handler.method2response[java_organizeImports::request::kMethodInfo] = [](Reader& visitor) + handler.method2response[java_organizeImports::request::kMethodInfo] = [](Reader& visitor) + { + if (visitor.HasMember("error")) { - if (visitor.HasMember("error")) - return Rsp_Error::ReflectReader(visitor); + return Rsp_Error::ReflectReader(visitor); + } - return java_organizeImports::response::ReflectReader(visitor); - }; + return java_organizeImports::response::ReflectReader(visitor); + }; - handler.method2response[java_resolveUnimplementedAccessors::request::kMethodInfo] = [](Reader& visitor) + handler.method2response[java_resolveUnimplementedAccessors::request::kMethodInfo] = [](Reader& visitor) + { + if (visitor.HasMember("error")) { - if (visitor.HasMember("error")) - return Rsp_Error::ReflectReader(visitor); + return Rsp_Error::ReflectReader(visitor); + } - return java_resolveUnimplementedAccessors::response::ReflectReader(visitor); - }; + return java_resolveUnimplementedAccessors::response::ReflectReader(visitor); + }; - handler.method2response[java_searchSymbols::request::kMethodInfo] = [](Reader& visitor) + handler.method2response[java_searchSymbols::request::kMethodInfo] = [](Reader& visitor) + { + if (visitor.HasMember("error")) { - if (visitor.HasMember("error")) - return Rsp_Error::ReflectReader(visitor); + 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); - }; + 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); - }; + 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); - }; + 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) - { + 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); }; - return td_declaration::request::ReflectReader(visitor); - }; - handler.method2request[td_willSaveWaitUntil::request::kMethodInfo] = [](Reader& 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")) { - 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); - }; + return Rsp_Error::ReflectReader(visitor); + } + return td_willSaveWaitUntil::request::ReflectReader(visitor); + }; - handler.method2request[td_links::request::kMethodInfo] = [](Reader& visitor) - { + handler.method2request[td_highlight::request::kMethodInfo] = [](Reader& visitor) + { return td_highlight::request::ReflectReader(visitor); }; - return td_links::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) - { + handler.method2request[td_linkResolve::request::kMethodInfo] = [](Reader& visitor) + { return td_linkResolve::request::ReflectReader(visitor); }; - return td_linkResolve::request::ReflectReader(visitor); - }; + handler.method2request[td_symbol::request::kMethodInfo] = [](Reader& visitor) + { return td_symbol::request::ReflectReader(visitor); }; - handler.method2request[td_symbol::request::kMethodInfo] = [](Reader& visitor) - { + handler.method2request[td_formatting::request::kMethodInfo] = [](Reader& visitor) + { return td_formatting::request::ReflectReader(visitor); }; - return td_symbol::request::ReflectReader(visitor); - }; + handler.method2request[td_hover::request::kMethodInfo] = [](Reader& visitor) + { return td_hover::request::ReflectReader(visitor); }; - handler.method2request[td_formatting::request::kMethodInfo] = [](Reader& visitor) - { + handler.method2request[td_implementation::request::kMethodInfo] = [](Reader& visitor) + { return td_implementation::request::ReflectReader(visitor); }; - return td_formatting::request::ReflectReader(visitor); - }; + handler.method2request[td_didRenameFiles::request::kMethodInfo] = [](Reader& visitor) + { return td_didRenameFiles::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); - }; + 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); + 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 index 504caa3e65..82f68701ca 100644 --- a/graphics/asymptote/LspCpp/src/lsp/initialize.cpp +++ b/graphics/asymptote/LspCpp/src/lsp/initialize.cpp @@ -3,43 +3,49 @@ 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; + 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; - } + 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) +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); - } + 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 index d070f22be1..964d1ba8cd 100644 --- a/graphics/asymptote/LspCpp/src/lsp/lsp.cpp +++ b/graphics/asymptote/LspCpp/src/lsp/lsp.cpp @@ -2,10 +2,8 @@ #include "LibLsp/lsp/lru_cache.h" - #include <rapidjson/writer.h> - #include <stdio.h> #include <iostream> #include "LibLsp/lsp/location_type.h" @@ -25,6 +23,9 @@ #include "LibLsp/lsp/AbsolutePath.h" #ifdef _WIN32 +#ifndef NOMINMAX +#define NOMINMAX +#endif #include <Windows.h> #else #include <climits> @@ -46,399 +47,415 @@ #include <boost/uuid/uuid_generators.hpp> // namespace - - -lsTextDocumentIdentifier -lsVersionedTextDocumentIdentifier::AsTextDocumentIdentifier() const { - lsTextDocumentIdentifier result; - result.uri = uri; - return result; +lsTextDocumentIdentifier lsVersionedTextDocumentIdentifier::AsTextDocumentIdentifier() const +{ + lsTextDocumentIdentifier result; + result.uri = uri; + return result; } +lsPosition::lsPosition() +{ +} +lsPosition::lsPosition(int line, int character) : line(line), character(character) +{ +} -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==(lsPosition const& 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; +bool lsPosition::operator<(lsPosition const& 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); +std::string lsPosition::ToString() const +{ + return std::to_string(line) + ":" + std::to_string(character); } -const lsPosition lsPosition::kZeroPosition = lsPosition(); +lsPosition const lsPosition::kZeroPosition = lsPosition(); -lsRange::lsRange() {} -lsRange::lsRange(lsPosition start, lsPosition end) : start(start), end(end) {} +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==(lsRange const& 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; +bool lsRange::operator<(lsRange const& 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(); + 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; +lsLocation::lsLocation() +{ +} +lsLocation::lsLocation(lsDocumentUri uri, lsRange range) : uri(uri), range(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 lsLocation::operator==(lsLocation const& o) const +{ + return uri == o.uri && range == o.range; } -bool lsTextEdit::operator==(const lsTextEdit& that) { - return range == that.range && newText == that.newText; +bool lsLocation::operator<(lsLocation const& o) const +{ + return std::make_tuple(uri.raw_uri_, range) < std::make_tuple(o.uri.raw_uri_, o.range); } -std::string lsTextEdit::ToString() const +bool lsTextEdit::operator==(lsTextEdit const& that) { - std::stringstream ss; - ss << "Range:" << range.ToString() << std::endl; - ss << "newText:" << newText << std::endl; - return ss.str(); + return range == that.range && newText == that.newText; } -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); - } +std::string lsTextEdit::ToString() const +{ + std::stringstream ss; + ss << "Range:" << range.ToString() << std::endl; + ss << "newText:" << newText << std::endl; + return ss.str(); } -void Reflect(Reader& visitor, lsMarkedString& value) +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, LocationListEither::Either& value) +void Reflect(Reader& visitor, lsMarkedString& 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); - } - + REFLECT_MEMBER_START(); + REFLECT_MEMBER(language); + REFLECT_MEMBER(value); + REFLECT_MEMBER_END(); } - void Reflect(Writer& visitor, LocationListEither::Either& value) +void Reflect(Reader& visitor, LocationListEither::Either& value) { - if (value.first) - { - Reflect(visitor, value.first.value()); - } - else if (value.second) - { - Reflect(visitor, value.second.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.HasMember("command")) + { + if (visitor["command"]->IsString()) { - if(visitor["command"]->IsString()) - { - Reflect(visitor, value.first); - } - else - { - Reflect(visitor, value.second); - } + Reflect(visitor, value.first); } else { - if (visitor.HasMember("diagnostics") || visitor.HasMember("edit")) - { - Reflect(visitor, value.second); - } - else - { - Reflect(visitor, value.first); - } + Reflect(visitor, value.second); } - -} - - -void Reflect(Reader& visitor, lsWorkspaceEdit::Either& value) -{ - - - if(visitor.HasMember("textDocument")) + } + else + { + if (visitor.HasMember("diagnostics") || visitor.HasMember("edit")) { - Reflect(visitor, value.first); + Reflect(visitor, value.second); } else { - Reflect(visitor, value.second); + 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"); + 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 + JsonReader visitor {&document}; + try + { + if (find->value == "create") { - 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(); - } + auto ptr = std::make_unique<lsCreateFile>(); + auto temp = ptr.get(); + Reflect(visitor, *temp); + return ptr.release(); } - catch (std::exception&) + 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(); } - return nullptr; + } + catch (std::exception&) + { + } + return nullptr; } - void Reflect(Writer& visitor, ResourceOperation* value) +void Reflect(Writer& visitor, ResourceOperation* value) { - if(!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") { - throw std::invalid_argument("ResourceOperation value is nullptr"); + jsonType = rapidjson::kNullType; } - if (value->kind == "create") + else if (data == "true") { - auto temp = (lsCreateFile*)value; - Reflect(visitor, *temp); + jsonType = rapidjson::kTrueType; } - else if (value->kind == "rename") + else if (data == "false") { - auto temp = (lsRenameFile*)value; - Reflect(visitor, *temp); + jsonType = rapidjson::kFalseType; } - else if (value->kind == "delete") + else if (data[0] == '{') { - - auto temp = (lsDeleteFile*)value; - Reflect(visitor, *temp); + jsonType = rapidjson::kObjectType; } - -} - -int lsp::Any::GuessType() -{ - if (!data.empty()) + else if (data[0] == '[') { - 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; - } + if (data.size() >= 2 && data[1] == '{') + { + jsonType = rapidjson::kStringType; + } + else + { + jsonType = rapidjson::kArrayType; + } + } + else if (data[0] == '"') + { + jsonType = rapidjson::kStringType; } else { - if (jsonType != kUnKnown) - return jsonType; - jsonType = rapidjson::kNullType; + jsonType = rapidjson::kNumberType; } - return jsonType; + } + else + { + if (jsonType != kUnKnown) + { + return jsonType; + } + jsonType = rapidjson::kNullType; + } + return jsonType; } int lsp::Any::GetType() { - if (jsonType == Type::kUnKnown) + if (jsonType == Type::kUnKnown) + { + if (data.empty()) { - 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(); + jsonType = rapidjson::kNullType; + return jsonType; } - 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); - } + 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(); + jsonType = _type; + data.swap(_data); + GetType(); } -void lsp::Any::SetJsonString(const std::string& _data, Type _type) +void lsp::Any::SetJsonString(std::string const& _data, Type _type) { - jsonType = _type; - data = (_data); - GetType(); + 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; + data.swap(arg.data); + int const temp = jsonType; + jsonType = arg.jsonType; + arg.jsonType = temp; } -class JsonReaderForAny : public JsonReader +class JsonReaderForAny : public JsonReader { public: - JsonReaderForAny() - : JsonReader(&document) - { - } - rapidjson::Document document; + JsonReaderForAny() : JsonReader(&document) + { + } + rapidjson::Document document; }; bool lsp::Any::GetForMapHelper(std::string& value) { - return Get(value); + return Get(value); } bool lsp::Any::GetForMapHelper(optional<std::string>& value) { - return Get(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); + 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) - { - - } + 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>(); + 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(); + auto _temp = static_cast<JsonWriterForAny*>(writer.get()); + data = _temp->output.GetString(); + GuessType(); } namespace @@ -467,219 +484,222 @@ namespace } } #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; - } - } -} +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; + } +} +} // namespace 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); - } + //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"; + kind = "create"; } lsDeleteFile::lsDeleteFile() { - kind = "delete"; + kind = "delete"; } lsRenameFile::lsRenameFile() { - kind = "rename"; + kind = "rename"; } - -void Reflect(Reader& visitor, optional< SelectionRange* >& value) +void Reflect(Reader& visitor, optional<SelectionRange*>& value) { - if (visitor.IsNull()) { - visitor.GetNull(); - return; - } + if (visitor.IsNull()) + { + visitor.GetNull(); + return; + } - SelectionRange* entry_value = nullptr; + SelectionRange* entry_value = nullptr; + std::unique_ptr<SelectionRange> ptr = std::make_unique<SelectionRange>(); + SelectionRange* temp = ptr.get(); + Reflect(visitor, *temp); - std::unique_ptr<SelectionRange> ptr = std::make_unique<SelectionRange>(); - SelectionRange* temp = ptr.get(); - Reflect(visitor, *temp); - - entry_value = ptr.release(); - value = (entry_value); - + 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); - + if (!value) + { + throw std::invalid_argument("ResourceOperation value is nullptr"); + } + Reflect(visitor, *value); } - std::string make_file_scheme_uri(const std::string& absolute_path) +std::string make_file_scheme_uri(std::string const& 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_; + 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::BuildDoNotUse(std::string const& path) +{ + AbsolutePath p; + p.path = std::string(path); + return p; } +AbsolutePath::AbsolutePath() +{ +} -AbsolutePath::AbsolutePath() {} - - - -AbsolutePath::operator std::string() const { - return path; +AbsolutePath::operator std::string() const +{ + return path; } -bool AbsolutePath::operator==(const AbsolutePath& rhs) const { - return path == rhs.path; +bool AbsolutePath::operator==(AbsolutePath const& rhs) const +{ + return path == rhs.path; } -bool AbsolutePath::operator!=(const AbsolutePath& rhs) const { - return path != rhs.path; +bool AbsolutePath::operator!=(AbsolutePath const& rhs) const +{ + return path != rhs.path; } -bool AbsolutePath::operator<(const AbsolutePath& rhs) const +bool AbsolutePath::operator<(AbsolutePath const& rhs) const { - return path < rhs.path; + return path < rhs.path; } -bool AbsolutePath::operator>(const AbsolutePath& rhs) const +bool AbsolutePath::operator>(AbsolutePath const& rhs) const { - return path > rhs.path; + return path > rhs.path; } -void Reflect(Reader& visitor, AbsolutePath& value) { - value.path = visitor.GetString(); +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()); +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; +std::ostream& operator<<(std::ostream& out, AbsolutePath const& path) +{ + out << path.path; + return out; } -lsDocumentUri lsDocumentUri::FromPath(const AbsolutePath& path) { - lsDocumentUri result; - result.SetPath(path); - return result; +lsDocumentUri lsDocumentUri::FromPath(AbsolutePath const& 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"); - } +void lsDocumentUri::SetPath(AbsolutePath const& 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()); + // 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 + // TODO: proper fix #if defined(_WIN32) - t += "file:///"; + t += "file:///"; #else - t += "file://"; + t += "file://"; #endif - // clang-format off + // clang-format off for (char c : raw_uri_) switch (c) { case ' ': t += "%20"; break; @@ -695,330 +715,379 @@ void lsDocumentUri::SetPath(const AbsolutePath& path) { case '@': t += "%40"; break; default: t += c; break; } - // clang-format on - raw_uri_ = std::move(t); + // 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 lsDocumentUri::GetRawPath() const +{ + if (raw_uri_.compare(0, 8, "file:///")) + { + return raw_uri_; + } - std::string ret; + std::string ret; #if defined(_WIN32) - size_t i = 8; + size_t i = 8; #else - size_t i = 7; + 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]); + auto from_hex = [](unsigned char const& c) -> unsigned int + { + unsigned char c_from_zero_char = c - '0'; + return c_from_zero_char < 10 ? c_from_zero_char : (c | 32) - 'a' + 10; + }; + for (; i < raw_uri_.size(); i++) + { + if (i + 3 <= raw_uri_.size() && raw_uri_[i] == '%') + { + ret.push_back(static_cast<char>(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; + } + return ret; } -lsDocumentUri::lsDocumentUri() {} - - -lsDocumentUri::lsDocumentUri(const AbsolutePath& path) +lsDocumentUri::lsDocumentUri() { - SetPath(path); } -lsDocumentUri::lsDocumentUri(const lsDocumentUri& other): raw_uri_(other.raw_uri_) +lsDocumentUri::lsDocumentUri(AbsolutePath const& path) { + SetPath(path); } -bool lsDocumentUri::operator==(const lsDocumentUri& other) const { - return raw_uri_ == other.raw_uri_; +lsDocumentUri::lsDocumentUri(lsDocumentUri const& other) : raw_uri_(other.raw_uri_) +{ } -bool lsDocumentUri::operator==(const std::string& other) const +bool lsDocumentUri::operator==(lsDocumentUri const& other) const { - return raw_uri_ == other; + return raw_uri_ == other.raw_uri_; } +bool lsDocumentUri::operator==(std::string const& 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); - } - } +AbsolutePath lsDocumentUri::GetAbsolutePath() const +{ - return AbsolutePath(raw_uri_,false); + 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; - } +AbsolutePath::AbsolutePath(std::string const& 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(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. - +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 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::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(); - } + { + std::stringstream ss; + ss << "complete:" << complete << std::endl; + info += ss.str(); + } - return info; + 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 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"; - } + 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 (_kind == lsInsertTextFormat::PlainText) + { + return "PlainText"; + } + else if (_kind == lsInsertTextFormat::Snippet) + { + return "Snippet"; + } + else + { + return "Unknown"; + } +} + +std::string const& lsCompletionItem::InsertedContent() const { - if (textEdit) - return textEdit->newText; - if (insertText.has_value() && !insertText->empty()) - return insertText.value(); - return label; + if (textEdit) + { + return textEdit->newText; + } + if (insertText.has_value() && !insertText->empty()) + { + return insertText.value(); + } + return label; } std::string lsCompletionItem::DisplayText() { - if (detail) - { + if (detail) + { - return label + " in " + detail.value(); - } - return label; + 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 { - - - /** +{ + 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"; + char const* QuickFix = "quickfix"; - /** + /** * Base kind for refactoring actions: 'refactor' */ - const char* Refactor = "refactor"; + char const* Refactor = "refactor"; - /** + /** * Base kind for refactoring extraction actions: 'refactor.extract' * * Example extract actions: @@ -1026,18 +1095,18 @@ namespace JDT * - Extract method - Extract function - Extract variable - Extract interface * from class - ... */ - const char* RefactorExtract = "refactor.extract"; + char const* 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"; + char const* RefactorInline = "refactor.inline"; - /** + /** * Base kind for refactoring rewrite actions: 'refactor.rewrite' * * Example rewrite actions: @@ -1045,45 +1114,45 @@ namespace JDT * - Convert JavaScript function to class - Add or remove parameter - * Encapsulate field - Make method static - Move method to base class - ... */ - const char* RefactorRewrite = "refactor.rewrite"; + char const* RefactorRewrite = "refactor.rewrite"; - /** + /** * Base kind for source actions: `source` * * Source code actions apply to the entire file. */ - const char* Source = "source"; + char const* Source = "source"; - /** + /** * Base kind for an organize imports source action: `source.organizeImports` */ - const char* SourceOrganizeImports = "source.organizeImports"; + char const* SourceOrganizeImports = "source.organizeImports"; - const char* COMMAND_ID_APPLY_EDIT = "java.apply.workspaceEdit"; + char const* COMMAND_ID_APPLY_EDIT = "java.apply.workspaceEdit"; - }; +}; // namespace CodeActionKind - -} -Directory::Directory(const AbsolutePath& path) : path(path.path) { - lsp::EnsureEndsInSlash(this->path); +} // namespace JDT +Directory::Directory(AbsolutePath const& path) : path(path.path) +{ + lsp::EnsureEndsInSlash(this->path); } -bool Directory::operator==(const Directory& rhs) const { - return path == rhs.path; +bool Directory::operator==(Directory const& rhs) const +{ + return path == rhs.path; } -bool Directory::operator!=(const Directory& rhs) const { - return path != rhs.path; +bool Directory::operator!=(Directory const& rhs) const +{ + return path != rhs.path; } - - - Registration Registration::Create(const std::string& method) +Registration Registration::Create(std::string const& method) { - Registration reg; - reg.method = method; - const boost::uuids::uuid a_uuid = boost::uuids::random_generator()(); - reg.id = to_string(a_uuid); - return reg; + Registration reg; + reg.method = method; + boost::uuids::uuid const 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 index fba0edc30c..308388da37 100644 --- a/graphics/asymptote/LspCpp/src/lsp/lsp_diagnostic.cpp +++ b/graphics/asymptote/LspCpp/src/lsp/lsp_diagnostic.cpp @@ -1,75 +1,78 @@ #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==(lsDiagnostic const& rhs) const +{ + // Just check the important fields. + return range == rhs.range && message == rhs.message; } -bool lsDiagnostic::operator!=(const lsDiagnostic& rhs) const { - return !(*this == rhs); +bool lsDiagnostic::operator!=(lsDiagnostic const& 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"; + 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()) - { + if (data.has_value()) + { - info += "data:" + data.value().Data(); - info += "\n"; - } - return info; + info += "data:" + data.value().Data(); + info += "\n"; + } + return info; } -void lsResponseError::Write(Writer& visitor) { - auto& value = *this; - int code2 = static_cast<int>(this->code); +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(); + 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 index c87a047d3f..1ff7a3af2d 100644 --- a/graphics/asymptote/LspCpp/src/lsp/textDocument.cpp +++ b/graphics/asymptote/LspCpp/src/lsp/textDocument.cpp @@ -9,341 +9,399 @@ #include "LibLsp/lsp/textDocument/SemanticTokens.h" #include "LibLsp/JsonRpc/json.h" - constexpr unsigned SemanticTokenEncodingSize = 5; std::string to_string(SemanticTokenType _type) { - switch (_type) { + switch (_type) + { - case ls_namespace: return "namespace"; - /** + 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"; - } + 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; + 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"; + 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"; - } + 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; + 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 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"); +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); +bool operator==(SemanticToken const& l, SemanticToken const& 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; + std::vector<int32_t> result; + result.reserve(SemanticTokenEncodingSize * tokens.size()); + for (auto const& 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); - } + 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); - } + 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); - } + 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); - } + if (!visitor.IsString()) + { + Reflect(visitor, value.second); + } + else + { + Reflect(visitor, value.first); + } } - void Reflect(Reader& visitor, TextDocumentHover::Either& value) +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); - } + 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) +void Reflect(Reader& visitor, TextDocumentPrepareRenameResult& value) { - if (visitor.HasMember("placeholder")) - { - Reflect(visitor, value.second); - } - else - { - Reflect(visitor, value.first); - } + 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$; +namespace RefactorProposalUtility +{ +char const* APPLY_REFACTORING_COMMAND_ID = "java.action.applyRefactoringCommand"; +char const* EXTRACT_VARIABLE_ALL_OCCURRENCE_COMMAND = "extractVariableAllOccurrence"; +char const* EXTRACT_VARIABLE_COMMAND = "extractVariable"; +char const* EXTRACT_CONSTANT_COMMAND = "extractConstant"; +char const* EXTRACT_METHOD_COMMAND = "extractMethod"; +char const* EXTRACT_FIELD_COMMAND = "extractField"; +char const* CONVERT_VARIABLE_TO_FIELD_COMMAND = "convertVariableToField"; +char const* MOVE_FILE_COMMAND = "moveFile"; +char const* MOVE_INSTANCE_METHOD_COMMAND = "moveInstanceMethod"; +char const* MOVE_STATIC_MEMBER_COMMAND = "moveStaticMember"; +char const* MOVE_TYPE_COMMAND = "moveType"; +}; // namespace RefactorProposalUtility +namespace QuickAssistProcessor +{ - const char* CONVERT_ANONYMOUS_CLASS_TO_NESTED_COMMAND = "convertAnonymousClassToNestedCommand"; - }; +char const* SPLIT_JOIN_VARIABLE_DECLARATION_ID = + "org.eclipse.jdt.ls.correction.splitJoinVariableDeclaration.assist"; //$NON-NLS-1$ +char const* CONVERT_FOR_LOOP_ID = "org.eclipse.jdt.ls.correction.convertForLoop.assist"; //$NON-NLS-1$ +char const* ASSIGN_TO_LOCAL_ID = "org.eclipse.jdt.ls.correction.assignToLocal.assist"; //$NON-NLS-1$ +char const* ASSIGN_TO_FIELD_ID = "org.eclipse.jdt.ls.correction.assignToField.assist"; //$NON-NLS-1$ +char const* ASSIGN_PARAM_TO_FIELD_ID = "org.eclipse.jdt.ls.correction.assignParamToField.assist"; //$NON-NLS-1$ +char const* ASSIGN_ALL_PARAMS_TO_NEW_FIELDS_ID = + "org.eclipse.jdt.ls.correction.assignAllParamsToNewFields.assist"; //$NON-NLS-1$ +char const* ADD_BLOCK_ID = "org.eclipse.jdt.ls.correction.addBlock.assist"; //$NON-NLS-1$ +char const* EXTRACT_LOCAL_ID = "org.eclipse.jdt.ls.correction.extractLocal.assist"; //$NON-NLS-1$ +char const* EXTRACT_LOCAL_NOT_REPLACE_ID = + "org.eclipse.jdt.ls.correction.extractLocalNotReplaceOccurrences.assist"; //$NON-NLS-1$ +char const* EXTRACT_CONSTANT_ID = "org.eclipse.jdt.ls.correction.extractConstant.assist"; //$NON-NLS-1$ +char const* INLINE_LOCAL_ID = "org.eclipse.jdt.ls.correction.inlineLocal.assist"; //$NON-NLS-1$ +char const* CONVERT_LOCAL_TO_FIELD_ID = "org.eclipse.jdt.ls.correction.convertLocalToField.assist"; //$NON-NLS-1$ +char const* CONVERT_ANONYMOUS_TO_LOCAL_ID = + "org.eclipse.jdt.ls.correction.convertAnonymousToLocal.assist"; //$NON-NLS-1$ +char const* CONVERT_TO_STRING_BUFFER_ID = "org.eclipse.jdt.ls.correction.convertToStringBuffer.assist"; //$NON-NLS-1$ +char const* CONVERT_TO_MESSAGE_FORMAT_ID = "org.eclipse.jdt.ls.correction.convertToMessageFormat.assist"; //$NON-NLS-1$; +char const* EXTRACT_METHOD_INPLACE_ID = "org.eclipse.jdt.ls.correction.extractMethodInplace.assist"; //$NON-NLS-1$; - 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; - } +char const* CONVERT_ANONYMOUS_CLASS_TO_NESTED_COMMAND = "convertAnonymousClassToNestedCommand"; +}; // namespace QuickAssistProcessor +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; - } - } +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 index 893cc94552..0ed5872fca 100644 --- a/graphics/asymptote/LspCpp/src/lsp/utils.cpp +++ b/graphics/asymptote/LspCpp/src/lsp/utils.cpp @@ -15,11 +15,10 @@ #include "LibLsp/lsp/lsPosition.h" #include "utf8.h" -#ifdef _WIN32 +#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) @@ -28,6 +27,7 @@ #else #define ENSURE_STRING_MACRO_ARGUMENT(x) x #endif +#include <boost/utility.hpp> #include <boost/filesystem/path.hpp> #include <boost/filesystem/operations.hpp> #include <boost/algorithm/string.hpp> @@ -35,286 +35,336 @@ 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 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 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 AnyStartsWith(std::vector<std::string> const& values, std::string const& start) +{ + return std::any_of( + std::begin(values), std::end(values), [&start](std::string const& 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 StartsWithAny(std::string const& value, std::vector<std::string> const& startings) +{ + return std::any_of( + std::begin(startings), std::end(startings), + [&value](std::string const& 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 EndsWithAny(std::string const& value, std::vector<std::string> const& endings) +{ + return std::any_of( + std::begin(endings), std::end(endings), [&value](std::string const& 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; - }); +bool FindAnyPartial(std::string const& value, std::vector<std::string> const& values) +{ + return std::any_of( + std::begin(values), std::end(values), + [&value](std::string const& v) { return value.find(v) != std::string::npos; } + ); } -std::string GetDirName(std::string path) { +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); + 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 GetBaseName(std::string const& 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; +std::string StripFileType(std::string const& 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 ReplaceAll(std::string const& source, std::string const& from, std::string const& 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; + 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(); - } + 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); + // Care for the rest after last occurrence + result += source.substr(last_pos); - return result; + 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; - } +std::vector<std::string> SplitString(std::string const& str, std::string const& 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)); + // To get the last substring (or only, if delimiter is not found) + strings.emplace_back(str.substr(prev)); - return strings; + return strings; } -void EnsureEndsInSlash(std::string& path) { - if (path.empty() || path[path.size() - 1] != '/') - path += '/'; +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; +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(); +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. + // 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(); + 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; - } + 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; + t += (char)c; - if (c == '\n') - return is; - } + if (c == '\n') + { + return is; + } + } } -bool FileExists(const std::string& filename) { - std::ifstream cache(filename); - return cache.is_open(); +bool FileExists(std::string const& filename) +{ + std::ifstream cache(filename); + return cache.is_open(); } -optional<std::string> ReadContent(const AbsolutePath& filename) { +optional<std::string> ReadContent(AbsolutePath const& filename) +{ - std::ifstream cache; - cache.open(filename.path); + 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 {}; - } + 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::vector<std::string> ReadLinesWithEnding(AbsolutePath const& filename) +{ + std::vector<std::string> result; - std::ifstream input(filename.path); - for (std::string line; SafeGetline(input, line);) - result.emplace_back(line); + std::ifstream input(filename.path); + for (std::string line; SafeGetline(input, line);) + { + result.emplace_back(line); + } - return result; + 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()) { +bool WriteToFile(std::string const& filename, std::string const& content) +{ + std::ofstream file(filename, std::ios::out | std::ios::trunc | std::ios::binary); + if (!file.good()) + { - return false; - } + return false; + } - file << content; - return true; + file << content; + return true; } +std::string FormatMicroseconds(long long microseconds) +{ + long long milliseconds = microseconds / 1000; + long long remaining = microseconds - milliseconds; -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; + // Only show two digits after the dot. + while (remaining >= 100) + { + remaining /= 10; + } - return std::to_string(milliseconds) + "." + std::to_string(remaining) + "ms"; + 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; + } -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; + } - // 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"); } - // Replace "\n" with "\r|n". - output.replace(output.begin() + idx, output.begin() + idx + 1, "\r\n"); - } - - return output; + return output; } - - -bool IsAbsolutePath(const std::string& path) { - return IsUnixAbsolutePath(path) || IsWindowsAbsolutePath(path); +bool IsAbsolutePath(std::string const& path) +{ + return IsUnixAbsolutePath(path) || IsWindowsAbsolutePath(path); } -bool IsUnixAbsolutePath(const std::string& path) { - return !path.empty() && path[0] == '/'; +bool IsUnixAbsolutePath(std::string const& 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'); - }; +bool IsWindowsAbsolutePath(std::string const& 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]); + 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; +bool IsDirectory(std::string const& path) +{ + struct stat path_stat; - if (stat(path.c_str(), &path_stat) != 0) { - perror("cannot access path"); - return false; - } + if (stat(path.c_str(), &path_stat) != 0) + { + perror("cannot access path"); + return false; + } - return path_stat.st_mode & S_IFDIR; + 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::string ws2s(std::wstring const& wstr) +{ + BOOST_IF_CONSTEXPR(sizeof(wchar_t) == 2) + { + std::string narrow; + utf8::utf16to8(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; - } + else + { + std::string narrow; + utf8::utf32to8(wstr.begin(), wstr.end(), std::back_inserter(narrow)); + return narrow; + } +} +std::wstring s2ws(std::string const& str) +{ + std::wstring wide; + BOOST_IF_CONSTEXPR(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 @@ -322,291 +372,348 @@ bool IsDirectory(const std::string& path) { // 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 {}; +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; + } - // 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; + while (i < path.size()) + { + auto j = path.find('/', i); + if (j == std::string::npos) + { + j = path.size(); } - else { - if (!getcwd(tmp, sizeof tmp) && ensure_exists) - return {}; - resolved = tmp; + auto next_token = path.substr(i, j - i); + i = j + 1; + if (resolved.back() != '/') + { + resolved += '/'; } - - 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 {}; - } + 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*/); + // 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) { +AbsolutePath NormalizePath(std::string const& path0, bool ensure_exists, bool force_lower_on_windows) +{ #ifdef _WIN32 - std::wstring path = lsp::s2ws(path0); + std::wstring path = lsp::s2ws(path0); - wchar_t buffer[MAX_PATH] = (L""); + wchar_t buffer[MAX_PATH] = (L""); - // Normalize the path name, ie, resolve `..`. - unsigned long len = GetFullPathNameW(path.c_str(), MAX_PATH, buffer, nullptr); + // 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); - - // 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); + { + return {}; } + path = std::wstring(buffer, len); + } - // Empty paths have no meaning. - if (path.empty()) - return {}; + // 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. - /* + // 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]); + // 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(), '\\', '/'); - + // cquery assumes forward-slashes. + std::replace(path.begin(), path.end(), '\\', '/'); - return AbsolutePath(lsp::ws2s(path), false /*validate*/); + return AbsolutePath(lsp::ws2s(path), false /*validate*/); #else - return RealPathNotExpandSymlink(path0, ensure_exists); + 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++; +int GetOffsetForPosition(lsPosition position, std::string const& 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--; } - // 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--; + 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++; + } } - return int(i); + position.character--; + } + return int(i); } +lsPosition GetPositionForOffset(size_t offset, std::string const& 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 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++; - } +lsPosition CharPos(std::string const& search, char character, int character_offset) +{ + lsPosition result; + size_t index = 0; + while (index < search.size()) + { + char c = search[index]; + if (c == character) + { + break; } - 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; + if (c == '\n') + { + result.line += 1; + result.character = 0; } - 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; - } + else + { + result.character += 1; } + ++index; + } + assert(index < search.size()); + result.character += character_offset; + return result; } -void scanDirsNoRecursive(const std::wstring& rootPath, std::vector<std::wstring>& ret) +void scanDirsUseRecursive(std::wstring const& 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()); - } + 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 (std::exception const&) + { + continue; } + } } -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 scanDirsNoRecursive(std::wstring const& 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 scanFileNamesUseRecursive(const std::wstring& rootPath, std::vector<std::wstring>& ret, - std::wstring strSuf) +void scanFilesUseRecursive(std::wstring const& rootPath, std::vector<std::wstring>& ret, std::wstring suf) { - scanFilesUseRecursive(rootPath, ret, strSuf); - std::vector<std::wstring> names; - for (auto& it : ret) + 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 (it.size() >= rootPath.size()) + if (!fs::is_directory(*iter) && fs::is_regular_file(*iter)) + { + auto temp_path = iter->path().wstring(); + auto size = suf.size(); + if (!size) { - names.push_back(it.substr(rootPath.size())); + ret.push_back(std::move(temp_path)); } - } - ret.swap(names); -} + else + { -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) + 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 (std::exception const&) { - ret.push_back(ws2s(it)); + continue; } + } } -void scanFilesUseRecursive(const std::string& rootPath, std::vector<std::string>& ret, std::string strSuf) +void scanFileNamesUseRecursive(std::wstring const& rootPath, std::vector<std::wstring>& ret, std::wstring strSuf) { - std::vector<std::wstring> out; - scanFilesUseRecursive(s2ws(rootPath), out, s2ws(strSuf)); - for (auto& it : out) + scanFilesUseRecursive(rootPath, ret, strSuf); + std::vector<std::wstring> names; + for (auto& it : ret) + { + if (it.size() >= rootPath.size()) { - ret.push_back(ws2s(it)); + names.push_back(it.substr(rootPath.size())); } + } + ret.swap(names); } +void scanFileNamesUseRecursive(std::string const& 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(std::string const& 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)); + } } + +} // namespace lsp diff --git a/graphics/asymptote/LspCpp/src/lsp/working_files.cpp b/graphics/asymptote/LspCpp/src/lsp/working_files.cpp index 4eb4b29053..a77f763cda 100644 --- a/graphics/asymptote/LspCpp/src/lsp/working_files.cpp +++ b/graphics/asymptote/LspCpp/src/lsp/working_files.cpp @@ -8,167 +8,165 @@ using namespace lsp; struct WorkingFilesData { - std::map<AbsolutePath, std::shared_ptr<WorkingFile> > files; - std::mutex files_mutex; // Protects |d_ptr->files|. + 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) +WorkingFile::WorkingFile(WorkingFiles& _parent, AbsolutePath const& filename, std::string const& buffer_content) + : filename(filename), directory(filename), parent(_parent), counter(0), buffer_content(buffer_content) { - directory = Directory(GetDirName(filename.path)); + 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) +WorkingFile::WorkingFile(WorkingFiles& _parent, AbsolutePath const& 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() : d_ptr(new WorkingFilesData()) { } WorkingFiles::~WorkingFiles() { delete d_ptr; - } - - -void WorkingFiles::CloseFilesInDirectory(const std::vector<Directory>& directories) +void WorkingFiles::CloseFilesInDirectory(std::vector<Directory> const& 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& it : d_ptr->files) { for (auto& dir : directories) { - if (it.second->directory == dir) { + if (it.second->directory == dir) + { files_to_be_delete.emplace_back(it.first); } } } - for(auto& it : files_to_be_delete) + 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::GetFileByFilename(AbsolutePath const& 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()) +std::shared_ptr<WorkingFile> WorkingFiles::GetFileByFilenameNoLock(AbsolutePath const& filename) +{ + auto const findIt = d_ptr->files.find(filename); + if (findIt != d_ptr->files.end()) { return findIt->second; } - return nullptr; + 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(); -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); + // The file may already be open. + if (auto file = GetFileByFilenameNoLock(filename)) + { + file->version = open.version; + file->buffer_content.swap(open.text); - return file; - } + return file; + } - const auto& it = d_ptr->files.insert({ filename,std::make_shared<WorkingFile>(*this,filename, std::move(open.text)) }); - return it.first->second; + auto const& 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(lsTextDocumentDidChangeParams const& change) +{ + std::lock_guard<std::mutex> lock(d_ptr->files_mutex); -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); + 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 (lsTextDocumentContentChangeEvent const& 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; + 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; +bool WorkingFiles::OnClose(lsTextDocumentIdentifier const& close) +{ + std::lock_guard<std::mutex> lock(d_ptr->files_mutex); + + AbsolutePath filename = close.uri.GetAbsolutePath(); + auto const 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::shared_ptr<WorkingFile> WorkingFiles::OnSave(lsTextDocumentIdentifier const& _save) { std::lock_guard<std::mutex> lock(d_ptr->files_mutex); AbsolutePath filename = _save.uri.GetAbsolutePath(); - const auto findIt = d_ptr->files.find(filename); + auto const 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 {}; - + return {}; } -bool WorkingFiles::GetFileBufferContent(std::shared_ptr<WorkingFile>&file, std::string& out) +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 true; } - return false; + return false; } bool WorkingFiles::GetFileBufferContent(std::shared_ptr<WorkingFile>& file, std::wstring& out) { @@ -176,11 +174,12 @@ bool WorkingFiles::GetFileBufferContent(std::shared_ptr<WorkingFile>& file, std: if (file) { out = lsp::s2ws(file->buffer_content); - return true; + return true; } - return false; + return false; } -void WorkingFiles::Clear() { +void WorkingFiles::Clear() +{ std::lock_guard<std::mutex> lock(d_ptr->files_mutex); d_ptr->files.clear(); } |