diff options
Diffstat (limited to 'elpa/irony-20220110.849/server/src')
19 files changed, 0 insertions, 2355 deletions
diff --git a/elpa/irony-20220110.849/server/src/CMakeLists.txt b/elpa/irony-20220110.849/server/src/CMakeLists.txt deleted file mode 100644 index c516e70..0000000 --- a/elpa/irony-20220110.849/server/src/CMakeLists.txt +++ /dev/null @@ -1,111 +0,0 @@ -# XXX: if there are issues -# due to https://reviews.llvm.org/D30911 / SVN Revision 298424 -# then use the fallback when LLVM_VERSION VERSION_LESS 5.0.1 -find_package(Clang) - -if (Clang_FOUND) - # XXX: at least since Clang 8.0.0 - # it's looks like the 'libclang' IMPORTED target - # does not specify the following target property: - # INTERFACE_INCLUDE_DIRECTORIES ${CLANG_INCLUDE_DIRS} - # which is confirmed by https://github.com/Sarcasm/irony-mode/issues/530 - # so we work around this, - # but ideally Clang upstream should export fully usable IMPORTED targets - add_library(irony_libclang INTERFACE) - target_link_libraries(irony_libclang INTERFACE libclang) - target_include_directories(irony_libclang INTERFACE ${CLANG_INCLUDE_DIRS}) - - get_property(IRONY_CLANG_EXECUTABLE TARGET clang PROPERTY LOCATION) - execute_process( - COMMAND "${IRONY_CLANG_EXECUTABLE}" -print-resource-dir - OUTPUT_VARIABLE CLANG_RESOURCE_DIR - OUTPUT_STRIP_TRAILING_WHITESPACE - ) -else() - # fallback to historically FindLibClang.cmake - # and -resource-dir guess mecanism - include(CheckClangResourceDir) - find_package(LibClang REQUIRED) - check_clang_resource_dir() -endif() - -# not to be taken as a module-definition file to link on Windows -set_source_files_properties(Commands.def PROPERTIES HEADER_FILE_ONLY TRUE) - -if(MSVC) - # irony-server uses some code that breaks when iterator debugging is enabled - # - # The culprit is CommandLineArgumentParser who initialize its member - # 'Position', of type 'std::string::const_iterator', to 'Input.begin() - 1'. - # With checked iterator the begin() - 1 breaks in debug build. - add_definitions(/D_ITERATOR_DEBUG_LEVEL=0) -endif() - -add_executable(irony-server - support/CommandLineParser.cpp - support/CommandLineParser.h - support/iomanip_quoted.h - support/NonCopyable.h - support/CIndex.h - support/TemporaryFile.cpp - support/TemporaryFile.h - - Command.cpp - Commands.def - Command.h - CompDBCache.h - CompDBCache.cpp - Irony.cpp - Irony.h - TUManager.cpp - TUManager.h - - main.cpp) - -irony_target_set_cxx_standard(irony-server) - -target_include_directories(irony-server PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}) - -# retrieve the package version from irony.el -function(irony_find_package_version OUTPUT_VAR) - # this is a hack that force CMake to reconfigure, it is necessary to see if - # the version in irony.el has changed, this is not possible to add the - # definitions at build time - configure_file(${PROJECT_SOURCE_DIR}/../irony.el - ${CMAKE_CURRENT_BINARY_DIR}/irony.el - COPYONLY) - - set(version_header "\;\; Version: ") - file(STRINGS ${CMAKE_CURRENT_BINARY_DIR}/irony.el version - LIMIT_COUNT 1 - REGEX "^${version_header}*") - - if (NOT version) - message (FATAL_ERROR "couldn't find irony.el's version header!") - endif() - - string(LENGTH ${version_header} version_header_length) - string(SUBSTRING ${version} ${version_header_length} -1 package_version) - set(${OUTPUT_VAR} ${package_version} PARENT_SCOPE) -endfunction() - -irony_find_package_version(IRONY_PACKAGE_VERSION) -message(STATUS "Irony package version is '${IRONY_PACKAGE_VERSION}'") - -set_source_files_properties(main.cpp - PROPERTIES - COMPILE_DEFINITIONS IRONY_PACKAGE_VERSION=\"${IRONY_PACKAGE_VERSION}\") - -if (CLANG_RESOURCE_DIR) - # look for CLANG_RESOURCE_DIR_DIR usage in the code for an explanation - set_source_files_properties(TUManager.cpp - PROPERTIES - COMPILE_DEFINITIONS CLANG_RESOURCE_DIR=\"${CLANG_RESOURCE_DIR}\") -endif() - -target_link_libraries(irony-server irony_libclang) - -set_target_properties(irony-server - PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_BINDIR}) - -install(TARGETS irony-server DESTINATION ${CMAKE_INSTALL_BINDIR}) diff --git a/elpa/irony-20220110.849/server/src/Command.cpp b/elpa/irony-20220110.849/server/src/Command.cpp deleted file mode 100644 index 363b6cb..0000000 --- a/elpa/irony-20220110.849/server/src/Command.cpp +++ /dev/null @@ -1,278 +0,0 @@ -/** - * \file - * \author Guillaume Papin <guillaume.papin@epitech.eu> - * - * \brief Command parser definitions. - * - * This file is distributed under the GNU General Public License. See - * COPYING for details. - */ - -#include "Command.h" - -#include "support/CommandLineParser.h" - -#include <algorithm> -#include <cstdlib> -#include <functional> -#include <iostream> -#include <limits> -#include <map> - - -namespace { - -struct StringConverter { - StringConverter(std::string *dest) : dest_(dest) { - } - - bool operator()(const std::string &str) { - *dest_ = str; - return true; - } - -private: - std::string *dest_; -}; - -struct UnsignedIntConverter { - UnsignedIntConverter(unsigned *dest) : dest_(dest) { - } - - bool operator()(const std::string &str) { - char *end; - long num = std::strtol(str.c_str(), &end, 10); - - if (end != (str.c_str() + str.size())) - return false; - - if (errno == ERANGE) - return false; - - if (num < 0) - return false; - - unsigned long unum = static_cast<unsigned long>(num); - if (unum > std::numeric_limits<unsigned>::max()) - return false; - - *dest_ = unum; - return true; - } - -private: - unsigned *dest_; -}; - -/// Convert "on" and "off" to a boolean -struct OptionConverter { - OptionConverter(bool *dest) : dest_(dest) { - } - - bool operator()(const std::string &str) { - if (str == "on") { - *dest_ = true; - } else if (str == "off") { - *dest_ = false; - } else { - return false; - } - return true; - } - -private: - bool *dest_; -}; - -const std::map<std::string, PrefixMatchStyle> PREFIX_MATCH_STYLE_MAP = { - { "exact", PrefixMatchStyle::Exact }, - { "case-insensitive", PrefixMatchStyle::CaseInsensitive }, - { "smart-case", PrefixMatchStyle::SmartCase}, -}; - -/// Convert style to a PrefixMatchStyle -struct PrefixMatchStyleConverter { - PrefixMatchStyleConverter(PrefixMatchStyle *dest) : dest_(dest) { - } - - bool operator()(const std::string &str) { - auto res = PREFIX_MATCH_STYLE_MAP.find(str); - - if (res == PREFIX_MATCH_STYLE_MAP.cend()) { - return false; - } - *dest_ = res->second; - return true; - } - -private: - PrefixMatchStyle *dest_; -}; - -std::ostream &operator<<(std::ostream &os, PrefixMatchStyle style) { - for (auto it : PREFIX_MATCH_STYLE_MAP) { - if (it.second == style) { - os << it.first; - return os; - } - } - os << "UnknownStyle"; - return os; -} - - -} // unnamed namespace - -std::ostream &operator<<(std::ostream &os, const Command::Action &action) { - os << "Command::"; - - switch (action) { -#define X(sym, str, help) \ - case Command::sym: \ - os << #sym; \ - break; -#include "Commands.def" - } - return os; -} - -std::ostream &operator<<(std::ostream &os, const Command &command) { - os << "Command{action=" << command.action << ", " - << "file='" << command.file << "', " - << "unsavedFile='" << command.unsavedFile << "', " - << "dir='" << command.dir << "', " - << "line=" << command.line << ", " - << "column=" << command.column << ", " - << "prefix='" << command.prefix << "', " - << "caseStyle='" << command.style << "', " - << "flags=["; - bool first = true; - for (const std::string &flag : command.flags) { - if (!first) - os << ", "; - os << "'" << flag << "'"; - first = false; - } - os << "], " - << "opt=" << (command.opt ? "on" : "off"); - - return os << "}"; -} - -static Command::Action actionFromString(const std::string &actionStr) { -#define X(sym, str, help) \ - if (actionStr == str) \ - return Command::sym; - -#include "Commands.def" - - return Command::Unknown; -} - -CommandParser::CommandParser() : tempFile_("irony-server") { -} - -Command *CommandParser::parse(const std::vector<std::string> &argv) { - command_.clear(); - - if (argv.begin() == argv.end()) { - std::clog << "error: no command specified.\n" - "See 'irony-server help' to list available commands\n"; - return 0; - } - - const std::string &actionStr = argv[0]; - - command_.action = actionFromString(actionStr); - - bool readCompileOptions = false; - std::vector<std::function<bool(const std::string &)>> positionalArgs; - - switch (command_.action) { - case Command::SetDebug: - positionalArgs.push_back(OptionConverter(&command_.opt)); - break; - - case Command::Parse: - positionalArgs.push_back(StringConverter(&command_.file)); - readCompileOptions = true; - break; - - case Command::Complete: - positionalArgs.push_back(StringConverter(&command_.file)); - positionalArgs.push_back(UnsignedIntConverter(&command_.line)); - positionalArgs.push_back(UnsignedIntConverter(&command_.column)); - readCompileOptions = true; - break; - - case Command::GetType: - positionalArgs.push_back(UnsignedIntConverter(&command_.line)); - positionalArgs.push_back(UnsignedIntConverter(&command_.column)); - break; - - case Command::SetUnsaved: - positionalArgs.push_back(StringConverter(&command_.file)); - positionalArgs.push_back(StringConverter(&command_.unsavedFile)); - break; - - case Command::ResetUnsaved: - positionalArgs.push_back(StringConverter(&command_.file)); - break; - - case Command::Candidates: - positionalArgs.push_back(StringConverter(&command_.prefix)); - positionalArgs.push_back(PrefixMatchStyleConverter(&command_.style)); - break; - case Command::CompletionDiagnostics: - case Command::Diagnostics: - case Command::Help: - case Command::Exit: - // no-arguments commands - break; - - case Command::GetCompileOptions: - positionalArgs.push_back(StringConverter(&command_.dir)); - positionalArgs.push_back(StringConverter(&command_.file)); - break; - - case Command::Unknown: - std::clog << "error: invalid command specified: " << actionStr << "\n"; - return 0; - } - - auto argsBegin = argv.begin() + 1; - const auto argsEnd = std::find(argsBegin, argv.end(), "--"); - const int argCount = std::distance(argsBegin, argsEnd); - - // compile options are provided after '--' - if (readCompileOptions && argsEnd != argv.end()) { - command_.flags.assign(std::next(argsEnd), argv.end()); - } - - if (argCount != static_cast<int>(positionalArgs.size())) { - std::clog << "error: invalid number of arguments for '" << actionStr - << "' (requires " << positionalArgs.size() << " got " << argCount - << ")\n"; - return 0; - } - - for (auto fn : positionalArgs) { - if (!fn(*argsBegin)) { - std::clog << "error: parsing command '" << actionStr - << "': invalid argument '" << *argsBegin << "'\n"; - return 0; - } - ++argsBegin; - } - - // '-' is used as a special file to inform that the buffer hasn't been saved - // on disk and only the buffer content is available. libclang needs a file, so - // this is treated as a special value for irony-server to create a temporary - // file for this. note that libclang will gladly accept '-' as a filename but - // we don't want to let this happen since irony already reads stdin. - if (command_.file == "-") { - command_.file = tempFile_.getPath(); - } - - return &command_; -} diff --git a/elpa/irony-20220110.849/server/src/Command.h b/elpa/irony-20220110.849/server/src/Command.h deleted file mode 100644 index 9f36aa4..0000000 --- a/elpa/irony-20220110.849/server/src/Command.h +++ /dev/null @@ -1,73 +0,0 @@ -/**-*-C++-*- - * \file - * \author Guillaume Papin <guillaume.papin@epitech.eu> - * - * \brief Command parser declarations. - * - * This file is distributed under the GNU General Public License. See - * COPYING for details. - */ - -#ifndef IRONY_MODE_SERVER_COMMAND_H_ -#define IRONY_MODE_SERVER_COMMAND_H_ - -#include "support/CIndex.h" -#include "support/TemporaryFile.h" -#include "Style.h" - -#include <iosfwd> -#include <string> -#include <vector> - -class TemporaryFile; - -// TODO: a tagged union? -struct Command { - Command() { - clear(); - } - - void clear() { - action = Unknown; - flags.clear(); - file.clear(); - unsavedFile.clear(); - dir.clear(); - prefix.clear(); - style = PrefixMatchStyle::Exact; - line = 0; - column = 0; - opt = false; - } - -#define X(sym, str, desc) sym, - enum Action { -#include "Commands.def" - } action; - - std::vector<std::string> flags; - std::string file; - std::string unsavedFile; - std::string dir; - std::string prefix; - PrefixMatchStyle style; - unsigned line; - unsigned column; - bool opt; -}; - -std::ostream &operator<<(std::ostream &os, const Command::Action &action); -std::ostream &operator<<(std::ostream &os, const Command &command); - -class CommandParser { -public: - CommandParser(); - - Command *parse(const std::vector<std::string> &argv); - -private: - Command command_; - TemporaryFile tempFile_; -}; - -#endif // IRONY_MODE_SERVER_COMMAND_H_ diff --git a/elpa/irony-20220110.849/server/src/Commands.def b/elpa/irony-20220110.849/server/src/Commands.def deleted file mode 100644 index f99d8af..0000000 --- a/elpa/irony-20220110.849/server/src/Commands.def +++ /dev/null @@ -1,39 +0,0 @@ -/**-*-C++-*- - * \file - * \author Guillaume Papin <guillaume.papin@epitech.eu> - * - * \brief Command list. - * - * This file is distributed under the GNU General Public License. See - * COPYING for details. - */ - -#ifndef X -#error Please define the 'X(id, command, description)' macro before inclusion! -#endif - -X(Candidates, "candidates", - "PREFIX STYLE - print completion candidates (require previous complete). " - "STYLE is \"exact\", \"case-insensitive\" or \"smart-case\"") -X(Complete, "complete", - "FILE LINE COL [-- [COMPILE_OPTIONS...]] - perform code completion at a given location") -X(CompletionDiagnostics, "completion-diagnostics", - "print the diagnostics generated during complete") -X(Diagnostics, "diagnostics", "print the diagnostics of the last parse") -X(Exit, "exit", "exit interactive mode, print nothing") -X(GetCompileOptions, "get-compile-options", "BUILD_DIR FILE - " - "get compile options for FILE from JSON database in BUILD_DIR") -X(GetType, "get-type", "LINE COL - get type of symbol at a given location") -X(Help, "help", "show this message") -X(Parse, "parse", "FILE [-- [COMPILE_OPTIONS...]] - parse the given file") -X(ResetUnsaved, "reset-unsaved", "FILE - reset FILE, its content is up to date") -X(SetDebug, "set-debug", "ON|OFF - enable or disable verbose logging") -X(SetUnsaved, - "set-unsaved", - "FILE UNSAVED-CONTENT-FILE - tell irony-server that " - "UNSAVED-CONTENT-FILE contains the effective content of FILE") - -// sentinel value, should be the last one -X(Unknown, "<unkown>", "<unspecified>") - -#undef X diff --git a/elpa/irony-20220110.849/server/src/CompDBCache.cpp b/elpa/irony-20220110.849/server/src/CompDBCache.cpp deleted file mode 100644 index f79ec8c..0000000 --- a/elpa/irony-20220110.849/server/src/CompDBCache.cpp +++ /dev/null @@ -1,71 +0,0 @@ -#include "CompDBCache.h" - -#include <sys/stat.h> - -#include <cassert> - -CompDBCache::CompDBCache() - : db_(nullptr), mtime_(0) { -} - -CompDBCache::~CompDBCache() { - clear(); -} - -CXCompilationDatabase CompDBCache::fromDirectory(const std::string &buildDir, - CXCompilationDatabase_Error *error) { - assert(error != nullptr); - - const std::string jsonFilename = constructJsonDbFilename(buildDir); - const time_t mtime = modificationTime(jsonFilename); - - if (jsonFilename == filename_ && mtime != 0 && mtime == mtime_) { - // Using the cached compilation database. - // Just set the provided error code to indicate success. - *error = CXCompilationDatabase_NoError; - } else { - clear(); - - db_ = clang_CompilationDatabase_fromDirectory(buildDir.c_str(), error); - - if (mtime != 0 && *error == CXCompilationDatabase_NoError) { - // Successfully loaded a JSON compilation database. - // Cache the result. - filename_ = jsonFilename; - mtime_ = mtime; - } - } - - return db_; -} - -void CompDBCache::clear() { - if (db_) { - clang_CompilationDatabase_dispose(db_); - db_ = nullptr; - filename_.clear(); - mtime_ = 0; - } -} - -std::string CompDBCache::constructJsonDbFilename(const std::string &buildDir) const { - std::string ret = buildDir; - if (!buildDir.empty() && buildDir.back() != '/') - ret += '/'; - ret += "compile_commands.json"; - return ret; -} - -time_t CompDBCache::modificationTime(const std::string &filename) const { - time_t mtime = 0; -#ifdef _WIN32 - struct _stat st; - const int statRes = _stat(filename.c_str(), &st); -#else - struct stat st; - const int statRes = stat(filename.c_str(), &st); -#endif - if (statRes == 0) - mtime = st.st_mtime; - return mtime; -} diff --git a/elpa/irony-20220110.849/server/src/CompDBCache.h b/elpa/irony-20220110.849/server/src/CompDBCache.h deleted file mode 100644 index 568b790..0000000 --- a/elpa/irony-20220110.849/server/src/CompDBCache.h +++ /dev/null @@ -1,86 +0,0 @@ -/**-*-C++-*- - * \file - * \author Idar Tollefsen <idart@hotmail.com> - * - * \brief Creates a compilation database and caches it. - * - * Keeps a cache of the loaded compilation database, only creating a new - * one when needed. - * - * This file is distributed under the GNU General Public License. - * See COPYING for details. - */ - -#ifndef IRONY_MODE_COMPDBCACHE_H_ -#define IRONY_MODE_COMPDBCACHE_H_ - -#include "support/CIndex.h" -#include "support/NonCopyable.h" - -#include <ctime> -#include <string> - -class CompDBCache : public util::NonCopyable { -public: - CompDBCache(); - ~CompDBCache(); - - /** - * \brief Get a compilation database from a database found in a directory. - * - * This in essence a wrapper around - * \c clang_CompilationDatabase_fromDirectory() with added caching. - * It will either create a new compilation database or return the - * already loaded one (if any). - * - * This class owns the resulting compilation database. - * Therefore, unlike \c clang_CompilationDatabase_fromDirectory(), - * callers must NOT call \c clang_CompilationDatabase_dispose() on the - * returned compilation database. This class will handle that internally. - * - * \param buildDir Directory containing the database (such as - * "compile_commands.json") to create a compilation - * database from. - * \param error Error code from attempting to create a compilation - * database (\c CXCompilationDatabase_NoError on success). - * - * \return The compilation database or nullptr. - */ - CXCompilationDatabase fromDirectory(const std::string &buildDir, - CXCompilationDatabase_Error *error); - -private: - /** - * \brief Clear the cache. - * - * This will dispose the currently loaded compilation database (if any) by - * calling \c clang_CompilationDatabase_dispose() on it. And it will reset - * other internal housekeeping variables related to the caching of the - * compilation database. - */ - void clear(); - - /** - * \brief Construct JSON compilation database filename. - * - * \param buildDir Directory that might contain "compile_commands.json". - * - * \return Path to "compilation_commands.json" in \c buildDir. - */ - std::string constructJsonDbFilename(const std::string &buildDir) const; - - /** - * \brief Get modification time of a file. - * - * \param filename The file to get last modification time of. - * - * \return The modification time of \c filename or 0. - */ - time_t modificationTime(const std::string &filename) const; - - CXCompilationDatabase db_; - std::string filename_; - time_t mtime_; -}; - -#endif diff --git a/elpa/irony-20220110.849/server/src/Irony.cpp b/elpa/irony-20220110.849/server/src/Irony.cpp deleted file mode 100644 index 2157b32..0000000 --- a/elpa/irony-20220110.849/server/src/Irony.cpp +++ /dev/null @@ -1,638 +0,0 @@ -/** - * \file - * \author Guillaume Papin <guillaume.papin@epitech.eu> - * - * \brief irony-server "API" definitions. - * - * \sa Irony.h for more information. - * - * This file is distributed under the GNU General Public License. See - * COPYING for details. - */ - -#include "Irony.h" - -#include "support/iomanip_quoted.h" - -#include <algorithm> -#include <cassert> -#include <iostream> -#include <fstream> -#include <cctype> - -namespace { - -std::string cxStringToStd(CXString cxString) { - std::string stdStr; - - if (const char *cstr = clang_getCString(cxString)) { - stdStr = cstr; - } - - clang_disposeString(cxString); - return stdStr; -} - -const char *diagnosticSeverity(const CXDiagnostic &diagnostic) { - switch (clang_getDiagnosticSeverity(diagnostic)) { - case CXDiagnostic_Ignored: - return "ignored"; - case CXDiagnostic_Note: - return "note"; - case CXDiagnostic_Warning: - return "warning"; - case CXDiagnostic_Error: - return "error"; - case CXDiagnostic_Fatal: - return "fatal"; - } - - return "unknown"; -} - -void dumpDiagnostic(const CXDiagnostic &diagnostic) { - std::string file; - unsigned line = 0, column = 0, offset = 0; - CXSourceLocation location = clang_getDiagnosticLocation(diagnostic); - if (!clang_equalLocations(location, clang_getNullLocation())) { - CXFile cxFile; - -// clang_getInstantiationLocation() has been marked deprecated and -// is aimed to be replaced by clang_getExpansionLocation(). -#if CINDEX_VERSION >= 6 - clang_getExpansionLocation(location, &cxFile, &line, &column, &offset); -#else - clang_getInstantiationLocation(location, &cxFile, &line, &column, &offset); -#endif - - file = cxStringToStd(clang_getFileName(cxFile)); - } - - const char *severity = diagnosticSeverity(diagnostic); - - std::string message = cxStringToStd(clang_getDiagnosticSpelling(diagnostic)); - - std::cout << '(' << support::quoted(file) // - << ' ' << line // - << ' ' << column // - << ' ' << offset // - << ' ' << severity // - << ' ' << support::quoted(message) // - << ")\n"; -} - -bool readFileContent(const std::string &filename, - Irony::UnsavedBuffer &outBuf) { - std::ifstream ifs(filename.c_str(), - std::ios::in | std::ios::binary | std::ios::ate); - - if (!ifs.is_open()) { - return false; - } - - // FIXME: it's possible that this method of reading the file is 100% reliable, - // I can't confirm that tellg() is guaranteed to return a byte count. - // std::streamoff does not mention 'byte'. - // In practice it seems to work but this may be just luck. - // See also this discussion: - // - http://stackoverflow.com/questions/22984956/tellg-function-give-wrong-size-of-file/22986486#22986486 - auto nbytes = ifs.tellg(); - - if (nbytes == std::ifstream::pos_type(-1)) { - return false; - } - - outBuf.resize(nbytes); - ifs.seekg(0, std::ios::beg); - - ifs.read(&outBuf[0], outBuf.size()); - - if (!ifs){ - outBuf.clear(); - return false; - } - - return true; -} - -} // unnamed namespace - -Irony::Irony() - : activeTu_(nullptr), activeCompletionResults_(nullptr), debug_(false) { -} - -void Irony::parse(const std::string &file, - const std::vector<std::string> &flags) { - resetCache(); - activeTu_ = tuManager_.parse(file, flags, cxUnsavedFiles_); - file_ = file; - - if (activeTu_ == nullptr) { - std::cout << "(error . (" - << "parse-error" - << " \"failed to parse file\"" - << " " << support::quoted(file) << "))\n"; - return; - } - - std::cout << "(success . t)\n"; -} - -void Irony::diagnostics() const { - unsigned diagnosticCount; - - if (activeTu_ == nullptr) { - diagnosticCount = 0; - } else { - diagnosticCount = clang_getNumDiagnostics(activeTu_); - } - - std::cout << "(\n"; - - for (unsigned i = 0; i < diagnosticCount; ++i) { - CXDiagnostic diagnostic = clang_getDiagnostic(activeTu_, i); - - dumpDiagnostic(diagnostic); - - clang_disposeDiagnostic(diagnostic); - } - - std::cout << ")\n"; -} - -void Irony::resetCache() { - activeTu_ = nullptr; - - if (activeCompletionResults_ != nullptr) { - clang_disposeCodeCompleteResults(activeCompletionResults_); - activeCompletionResults_ = nullptr; - } -} - -void Irony::getType(unsigned line, unsigned col) const { - if (activeTu_ == nullptr) { - std::clog << "W: get-type - parse wasn't called\n"; - - std::cout << "nil\n"; - return; - } - - CXFile cxFile = clang_getFile(activeTu_, file_.c_str()); - CXSourceLocation sourceLoc = clang_getLocation(activeTu_, cxFile, line, col); - CXCursor cursor = clang_getCursor(activeTu_, sourceLoc); - - if (clang_Cursor_isNull(cursor)) { - // TODO: "error: no type at point"? - std::cout << "nil"; - return; - } - - CXType cxTypes[2]; - cxTypes[0] = clang_getCursorType(cursor); - cxTypes[1] = clang_getCanonicalType(cxTypes[0]); - - std::cout << "("; - - for (const CXType &cxType : cxTypes) { - CXString typeDescr = clang_getTypeSpelling(cxType); - std::string typeStr = clang_getCString(typeDescr); - clang_disposeString(typeDescr); - - if (typeStr.empty()) - break; - - std::cout << support::quoted(typeStr) << " "; - } - - std::cout << ")\n"; -} - -namespace { - -class CompletionChunk { -public: - explicit CompletionChunk(CXCompletionString completionString) - : completionString_(completionString) - , numChunks_(clang_getNumCompletionChunks(completionString_)) - , chunkIdx_(0) { - } - - bool hasNext() const { - return chunkIdx_ < numChunks_; - } - - void next() { - if (!hasNext()) { - assert(0 && "out of range completion chunk"); - abort(); - } - - ++chunkIdx_; - } - - CXCompletionChunkKind kind() const { - return clang_getCompletionChunkKind(completionString_, chunkIdx_); - } - - // TODO: operator>> so that one can re-use string allocated buffer - std::string text() const { - return cxStringToStd( - clang_getCompletionChunkText(completionString_, chunkIdx_)); - } - -private: - CXCompletionString completionString_; - unsigned int numChunks_; - unsigned chunkIdx_; -}; - -} // unnamed namespace - -void Irony::complete(const std::string &file, - unsigned line, - unsigned col, - const std::vector<std::string> &flags) { - resetCache(); - - if (CXTranslationUnit tu = - tuManager_.getOrCreateTU(file, flags, cxUnsavedFiles_)) { - activeCompletionResults_ = - clang_codeCompleteAt(tu, - file.c_str(), - line, - col, - const_cast<CXUnsavedFile *>(cxUnsavedFiles_.data()), - cxUnsavedFiles_.size(), - (clang_defaultCodeCompleteOptions() & - ~CXCodeComplete_IncludeCodePatterns) -#if HAS_BRIEF_COMMENTS_IN_COMPLETION - | - CXCodeComplete_IncludeBriefComments -#endif - ); - } - - if (activeCompletionResults_ == nullptr) { - std::cout << "(error . (" - << "complete-error" - << " \"failed to perform code completion\"" - << " " << support::quoted(file) << " " << line << " " << col - << "))\n"; - return; - } - - clang_sortCodeCompletionResults(activeCompletionResults_->Results, - activeCompletionResults_->NumResults); - - std::cout << "(success . t)\n"; -} - -namespace { - -bool hasUppercase(const std::string &prefix) -{ - for (char c : prefix) { - if (std::isupper(c)) { - return true; - } - } - return false; -} - -bool isEqual(const bool insensitive, const char a, const char b) -{ - if (insensitive) { - return std::tolower(a) == std::tolower(b); - } else { - return a == b; - } -} - -bool startsWith(const std::string& str, const std::string &prefix, bool caseInsensitive) -{ - if (str.length() < prefix.length()) { - return false; - } - - const auto charCmp = [&](const char a, const char b) { - return isEqual(caseInsensitive, a, b); - }; - - auto res = std::mismatch(prefix.begin(), prefix.end(), str.begin(), charCmp); - return res.first == prefix.end(); -} - -bool isStyleCaseInsensitive(const std::string &prefix, PrefixMatchStyle style) -{ - if (style == PrefixMatchStyle::SmartCase) { - // For SmartCase style, do case insensitive matching only there isn't upper - // case letter. - if (!hasUppercase(prefix)) { - style = PrefixMatchStyle::CaseInsensitive; - } - } - return style == PrefixMatchStyle::CaseInsensitive; -} - -} // unnamed namespace - -void Irony::completionDiagnostics() const { - unsigned diagnosticCount; - - if (activeCompletionResults_ == nullptr) { - diagnosticCount = 0; - } else { - diagnosticCount = - clang_codeCompleteGetNumDiagnostics(activeCompletionResults_); - } - - std::cout << "(\n"; - - for (unsigned i = 0; i < diagnosticCount; ++i) { - CXDiagnostic diagnostic = - clang_codeCompleteGetDiagnostic(activeCompletionResults_, i); - - dumpDiagnostic(diagnostic); - clang_disposeDiagnostic(diagnostic); - } - - std::cout << ")\n"; -} - -void Irony::candidates(const std::string &prefix, PrefixMatchStyle style) const { - if (activeCompletionResults_ == nullptr) { - std::cout << "nil\n"; - return; - } - - bool caseInsensitive = isStyleCaseInsensitive(prefix, style); - - CXCodeCompleteResults *completions = activeCompletionResults_; - - std::cout << "(\n"; - - // re-use the same buffers to avoid unnecessary allocations - std::string typedtext, brief, resultType, prototype, postCompCar; - - std::vector<unsigned> postCompCdr; - - for (unsigned i = 0; i < completions->NumResults; ++i) { - CXCompletionResult candidate = completions->Results[i]; - CXAvailabilityKind availability = - clang_getCompletionAvailability(candidate.CompletionString); - - unsigned priority = - clang_getCompletionPriority(candidate.CompletionString); - unsigned annotationStart = 0; - bool typedTextSet = false; - bool hasPrefix = true; - - - if (availability == CXAvailability_NotAccessible || - availability == CXAvailability_NotAvailable) { - continue; - } - - typedtext.clear(); - brief.clear(); - resultType.clear(); - prototype.clear(); - postCompCar.clear(); - postCompCdr.clear(); - - for (CompletionChunk chunk(candidate.CompletionString); chunk.hasNext(); - chunk.next()) { - char ch = 0; - - auto chunkKind = chunk.kind(); - - switch (chunkKind) { - case CXCompletionChunk_ResultType: - resultType = chunk.text(); - break; - - case CXCompletionChunk_TypedText: - case CXCompletionChunk_Text: - case CXCompletionChunk_Placeholder: - case CXCompletionChunk_Informative: - case CXCompletionChunk_CurrentParameter: - prototype += chunk.text(); - break; - - case CXCompletionChunk_LeftParen: ch = '('; break; - case CXCompletionChunk_RightParen: ch = ')'; break; - case CXCompletionChunk_LeftBracket: ch = '['; break; - case CXCompletionChunk_RightBracket: ch = ']'; break; - case CXCompletionChunk_LeftBrace: ch = '{'; break; - case CXCompletionChunk_RightBrace: ch = '}'; break; - case CXCompletionChunk_LeftAngle: ch = '<'; break; - case CXCompletionChunk_RightAngle: ch = '>'; break; - case CXCompletionChunk_Comma: ch = ','; break; - case CXCompletionChunk_Colon: ch = ':'; break; - case CXCompletionChunk_SemiColon: ch = ';'; break; - case CXCompletionChunk_Equal: ch = '='; break; - case CXCompletionChunk_HorizontalSpace: ch = ' '; break; - case CXCompletionChunk_VerticalSpace: ch = '\n'; break; - - case CXCompletionChunk_Optional: - // ignored for now - break; - } - - if (ch != 0) { - prototype += ch; - // commas look better followed by a space - if (ch == ',') { - prototype += ' '; - } - } - - if (typedTextSet) { - if (ch != 0) { - postCompCar += ch; - if (ch == ',') { - postCompCar += ' '; - } - } else if (chunkKind == CXCompletionChunk_Text || - chunkKind == CXCompletionChunk_TypedText) { - postCompCar += chunk.text(); - } else if (chunkKind == CXCompletionChunk_Placeholder || - chunkKind == CXCompletionChunk_CurrentParameter) { - postCompCdr.push_back(postCompCar.size()); - postCompCar += chunk.text(); - postCompCdr.push_back(postCompCar.size()); - } - } - - // Consider only the first typed text. The CXCompletionChunk_TypedText - // doc suggests that exactly one typed text will be given but at least - // in Objective-C it seems that more than one can appear, see: - // https://github.com/Sarcasm/irony-mode/pull/78#issuecomment-37115538 - if (chunkKind == CXCompletionChunk_TypedText && !typedTextSet) { - typedtext = chunk.text(); - if (!startsWith(typedtext, prefix, caseInsensitive)) { - hasPrefix = false; - break; - } - // annotation is what comes after the typedtext - annotationStart = prototype.size(); - typedTextSet = true; - } - } - - if (!hasPrefix) { - continue; - } - if (!typedTextSet) { - // clang may generate candidates without any typedText, and we may - // generate some output like: - // ("" 1 "bool" "" "hasUppercase(const std::string &prefix)" - // 0 ("") available) - // That will cause infinite completion in irony.el - continue; - } - -#if HAS_BRIEF_COMMENTS_IN_COMPLETION - brief = cxStringToStd( - clang_getCompletionBriefComment(candidate.CompletionString)); -#endif - - // see irony-completion.el#irony-completion-candidates - std::cout << '(' << support::quoted(typedtext) - << ' ' << priority - << ' ' << support::quoted(resultType) - << ' ' << support::quoted(brief) - << ' ' << support::quoted(prototype) - << ' ' << annotationStart - << " (" << support::quoted(postCompCar); - for (unsigned index : postCompCdr) - std::cout << ' ' << index; - std::cout << ")" - << ")\n"; - } - - std::cout << ")\n"; -} - -void Irony::computeCxUnsaved() { - cxUnsavedFiles_.clear(); - - for (const auto &p : filenameToContent_) { - CXUnsavedFile cxUnsavedFile; - - cxUnsavedFile.Filename = p.first.c_str(); - cxUnsavedFile.Contents = p.second.data(); - cxUnsavedFile.Length = p.second.size(); - cxUnsavedFiles_.push_back(cxUnsavedFile); - } -} - -void Irony::setUnsaved(const std::string &file, - const std::string &unsavedContentFile) { - resetCache(); - - UnsavedBuffer content; - if (!readFileContent(unsavedContentFile, content)) { - filenameToContent_.erase(file); - std::cout << "(error . (" - << "file-read-error" - << " \"failed to read unsaved buffer\"" - << " " << support::quoted(file) << " " - << support::quoted(unsavedContentFile) << ")\n"; - } else { - filenameToContent_[file] = content; - std::cout << "(success . t)\n"; - } - - computeCxUnsaved(); -} - -void Irony::resetUnsaved(const std::string &file) { - resetCache(); - - const auto erasedCount = filenameToContent_.erase(file); - - if (erasedCount == 0) { - std::cout << "(error . (" - << "no-such-entry" - << " \"failed reset unsaved buffer\"" - << " " << support::quoted(file) << ")\n"; - } else { - std::cout << "(success . t)\n"; - } - - computeCxUnsaved(); -} - -void Irony::getCompileOptions(const std::string &buildDir, - const std::string &file) const { -#if !(HAS_COMPILATION_DATABASE) - - (void)buildDir; - (void)file; - - CXString cxVersionString = clang_getClangVersion(); - - std::cout << "(error . (" - << "unsupported" - << " \"compilation database requires Clang >= 3.2\"" - << " " << support::quoted(clang_getCString(cxVersionString)) - << "))\n"; - - clang_disposeString(cxVersionString); - - return; - -#else - CXCompilationDatabase_Error error; - CXCompilationDatabase db = - compDBCache_.fromDirectory(buildDir.c_str(), &error); - - switch (error) { - case CXCompilationDatabase_CanNotLoadDatabase: - std::cout << "(error . (" - << "cannot-load-database" - << " \"failed to load compilation database from directory\"" - << " " << support::quoted(buildDir) << "))\n"; - return; - - case CXCompilationDatabase_NoError: - break; - } - - CXCompileCommands compileCommands = - clang_CompilationDatabase_getCompileCommands(db, file.c_str()); - - std::cout << "(success . (\n"; - - for (unsigned i = 0, numCompileCommands = - clang_CompileCommands_getSize(compileCommands); - i < numCompileCommands; ++i) { - CXCompileCommand compileCommand = - clang_CompileCommands_getCommand(compileCommands, i); - - std::cout << "(" - << "("; - for (unsigned j = 0, - numArgs = clang_CompileCommand_getNumArgs(compileCommand); - j < numArgs; ++j) { - CXString arg = clang_CompileCommand_getArg(compileCommand, j); - std::cout << support::quoted(clang_getCString(arg)) << " "; - clang_disposeString(arg); - } - - std::cout << ")" - << " . "; - - CXString directory = clang_CompileCommand_getDirectory(compileCommand); - std::cout << support::quoted(clang_getCString(directory)); - clang_disposeString(directory); - - std::cout << ")\n"; - } - - std::cout << "))\n"; - - clang_CompileCommands_dispose(compileCommands); -#endif -} diff --git a/elpa/irony-20220110.849/server/src/Irony.h b/elpa/irony-20220110.849/server/src/Irony.h deleted file mode 100644 index 66968f5..0000000 --- a/elpa/irony-20220110.849/server/src/Irony.h +++ /dev/null @@ -1,147 +0,0 @@ -/**-*-C++-*- - * \file - * \author Guillaume Papin <guillaume.papin@epitech.eu> - * - * \brief irony-server "API" declarations. - * - * Contains the commands that the Emacs package relies on. These commands are - * mostly wrappers around a subset of the features provided by libclang. Command - * results are printed to \c std::cout as s-expr, in order to make it easy for - * Emacs to consume. - * - * This file is distributed under the GNU General Public License. See - * COPYING for details. - */ - -#ifndef IRONY_MODE_SERVER_IRONY_H_ -#define IRONY_MODE_SERVER_IRONY_H_ - -#include "TUManager.h" - -#include "CompDBCache.h" -#include "Style.h" - -#include <string> -#include <vector> - -class Irony { -public: - // use std::string over std::vector<char> because I have some doubts - // that libclang expect unsaved buffers to be a null terminated C strings - typedef std::string UnsavedBuffer; - -public: - Irony(); - - bool isDebugEnabled() const { - return debug_; - } - - /// \name Command - /// \{ - - /// \brief Set or unset debugging of commands. - void setDebug(bool enable) { - debug_ = enable; - } - - /// Parse or reparse the given file and compile options. - /// - /// If the compile options have changed, the translation unit is re-created to - /// take this into account. - /// - /// Output \c nil or \c t, whether or not parsing the translation unit - /// succeeded. - /// - /// \sa diagnostics(), getType() - void parse(const std::string &file, const std::vector<std::string> &flags); - - /// Parse the given file for code completion. - /// - /// Shares the same semantics and output as \c parse(). - /// - /// \sa candidates(), completionDiagnostics() - void complete(const std::string &file, - unsigned line, - unsigned col, - const std::vector<std::string> &flags); - - void setUnsaved(const std::string &file, - const std::string &unsavedContentFile); - - void resetUnsaved(const std::string &file); - - /// \} - - /// \name Queries - /// \{ - - /// \brief Retrieve the last parse diagnostics for the given file. - /// - /// \pre parse() was called. - void diagnostics() const; - - /// \brief Get types of symbol at a given location. - /// - /// Example: - /// - /// \code - /// typedef int MyType; - /// MyType a; - /// \endcode - /// - /// Type of cursor location for 'a' is: - /// - /// \code{.el} - /// ("MyType" "int") - /// \endcode - /// - /// TODO: test with CXString(), seems to be twice the same string - /// - void getType(unsigned line, unsigned col) const; - - /// Get all the completion candidates. - /// - /// \pre complete() was called. - void candidates(const std::string &prefix, PrefixMatchStyle style) const; - - /// Get the diagnostics produced by the last \c complete(). - /// - /// \pre complete() was called. - void completionDiagnostics() const; - - /// \brief Get compile options from JSON database. - /// - /// \param buildDir Directory containing compile_commands.json - /// \param file File to obtain compile commands for. - /// - /// Example output: - /// - /// \code{.el} - /// ( - /// (("-Wfoo" "-DBAR" "-Iqux") . "/path/to/working/directory") - /// (("-Wfoo-alt" "-DBAR_ALT" "-Iqux/alt") . "/alt/working/directory") - /// ) - /// \endcode - /// - void getCompileOptions(const std::string &buildDir, - const std::string &file) const; - - /// \} - -private: - void resetCache(); - void computeCxUnsaved(); - -private: - mutable CompDBCache compDBCache_; - TUManager tuManager_; - std::map<std::string, UnsavedBuffer> filenameToContent_; - CXTranslationUnit activeTu_; - std::string file_; - std::vector<CXUnsavedFile> cxUnsavedFiles_; - CXCodeCompleteResults *activeCompletionResults_; - bool debug_; -}; - -#endif // IRONY_MODE_SERVER_IRONY_H_ diff --git a/elpa/irony-20220110.849/server/src/Style.h b/elpa/irony-20220110.849/server/src/Style.h deleted file mode 100644 index 52adb5e..0000000 --- a/elpa/irony-20220110.849/server/src/Style.h +++ /dev/null @@ -1,17 +0,0 @@ -/**-*-C++-*- - * \file - * - * \brief Style definition. - * - * This file is distributed under the GNU General Public License. See - * COPYING for details. - */ -#ifndef IRONY_MODE_SERVER_STYLE_H_ -#define IRONY_MODE_SERVER_STYLE_H_ - -enum class PrefixMatchStyle { - Exact, CaseInsensitive, SmartCase, -}; - - -#endif //IRONY_MODE_SERVER_STYLE_H_ diff --git a/elpa/irony-20220110.849/server/src/TUManager.cpp b/elpa/irony-20220110.849/server/src/TUManager.cpp deleted file mode 100644 index afbdc82..0000000 --- a/elpa/irony-20220110.849/server/src/TUManager.cpp +++ /dev/null @@ -1,182 +0,0 @@ -/** - * \file - * \author Guillaume Papin <guillaume.papin@epitech.eu> - * - * \brief See TUManager.hh - * - * This file is distributed under the GNU General Public License. See - * COPYING for details. - * - */ - -#include "TUManager.h" - -#include <iostream> - -TUManager::TUManager() - : index_(clang_createIndex(0, 0)) - , translationUnits_() - , parseTUOptions_(clang_defaultEditingTranslationUnitOptions()) { - - // this seems necessary to trigger "correct" reparse (/codeCompleteAt) - // clang_reparseTranslationUnit documentation states: - // - // > * \param TU The translation unit whose contents will be re-parsed. The - // > * translation unit must originally have been built with - // > * \c clang_createTranslationUnitFromSourceFile(). - // - // clang_createTranslationUnitFromSourceFile() is just a call to - // clang_parseTranslationUnit() with - // CXTranslationUnit_DetailedPreprocessingRecord enabled but because we want - // some other flags to be set we can't just call - // clang_createTranslationUnitFromSourceFile() - parseTUOptions_ |= CXTranslationUnit_DetailedPreprocessingRecord; - -#if HAS_BRIEF_COMMENTS_IN_COMPLETION - parseTUOptions_ |= CXTranslationUnit_IncludeBriefCommentsInCodeCompletion; -#endif - - // XXX: A bug in old version of Clang (at least '3.1-8') caused the completion - // to fail on the standard library types when - // CXTranslationUnit_PrecompiledPreamble is used. We disable this option for - // old versions of libclang. As a result the completion will work but - // significantly slower. - // - // -- https://github.com/Sarcasm/irony-mode/issues/4 - if (CINDEX_VERSION < 6) { - parseTUOptions_ &= ~CXTranslationUnit_PrecompiledPreamble; - } - -#if CINDEX_VERSION >= 34 - // Keep going even after fatal errors, or syntax checking will stop after the - // first error. For instance unused variables will not be reported until the - // error has been fixed. - parseTUOptions_ |= CXTranslationUnit_KeepGoing; -#endif -} - -TUManager::~TUManager() { - clang_disposeIndex(index_); -} - -CXTranslationUnit &TUManager::tuRef(const std::string &filename, - const std::vector<std::string> &flags) { - CXTranslationUnit &tu = translationUnits_[filename]; - - // if the flags changed since the last time, invalidate the translation unit - auto &flagsCache = flagsPerFileCache_[filename]; - if (flagsCache.size() != flags.size() || - !std::equal(flagsCache.begin(), flagsCache.end(), flags.begin())) { - if (tu) { - clang_disposeTranslationUnit(tu); - tu = nullptr; - } - // remember the flags for the next parse - flagsCache = flags; - } - return tu; -} - -CXTranslationUnit -TUManager::parse(const std::string &filename, - const std::vector<std::string> &flags, - const std::vector<CXUnsavedFile> &unsavedFiles) { - CXTranslationUnit &tu = tuRef(filename, flags); - - if (tu == nullptr) { - std::vector<const char *> argv; - -#ifdef CLANG_RESOURCE_DIR - // Make sure libclang find its builtin headers, this is a known issue with - // libclang, see: - // - http://lists.cs.uiuc.edu/pipermail/cfe-dev/2012-July/022893.html - // - // > Make sure that Clang is using its own . It will be in a directory - // > ending in clang/3.2/include/ where 3.2 is the version of clang that you - // > are using. You may need to explicitly add it to your header search. - // > Usually clang finds this directory relative to the executable with - // > CompilerInvocation::GetResourcesPath(Argv0, MainAddr), but using just - // > the libraries, it can't automatically find it. - argv.push_back("-resource-dir"); - argv.push_back(CLANG_RESOURCE_DIR); -#endif - - for (auto &flag : flags) { - argv.push_back(flag.c_str()); - } - - tu = clang_parseTranslationUnit( - index_, - filename.c_str(), - argv.data(), - static_cast<int>(argv.size()), - const_cast<CXUnsavedFile *>(unsavedFiles.data()), - unsavedFiles.size(), - parseTUOptions_); - } - - if (tu == nullptr) { - std::clog << "error: libclang couldn't parse '" << filename << "'\n"; - return nullptr; - } - - // Reparsing is necessary to enable optimizations. - // - // From the clang mailing list (cfe-dev): - // From: Douglas Gregor - // Subject: Re: Clang indexing library performance - // ... - // You want to use the "default editing options" when parsing the translation - // unit - // clang_defaultEditingTranslationUnitOptions() - // and then reparse at least once. That will enable the various - // code-completion optimizations that should bring this time down - // significantly. - if (clang_reparseTranslationUnit( - tu, - unsavedFiles.size(), - const_cast<CXUnsavedFile *>(unsavedFiles.data()), - clang_defaultReparseOptions(tu))) { - // a 'fatal' error occured (even a diagnostic is impossible) - clang_disposeTranslationUnit(tu); - std::clog << "error: libclang couldn't reparse '" << filename << "'\n"; - tu = 0; - return nullptr; - } - - return tu; -} - -CXTranslationUnit -TUManager::getOrCreateTU(const std::string &filename, - const std::vector<std::string> &flags, - const std::vector<CXUnsavedFile> &unsavedFiles) { - if (auto tu = tuRef(filename, flags)) - return tu; - - return parse(filename, flags, unsavedFiles); -} - -void TUManager::invalidateCachedTU(const std::string &filename) { - TranslationUnitsMap::iterator it = translationUnits_.find(filename); - - if (it != translationUnits_.end()) { - if (CXTranslationUnit &tu = it->second) - clang_disposeTranslationUnit(tu); - - translationUnits_.erase(it); - } -} - -void TUManager::invalidateAllCachedTUs() { - TranslationUnitsMap::iterator it = translationUnits_.begin(); - - while (it != translationUnits_.end()) { - if (CXTranslationUnit &tu = it->second) { - clang_disposeTranslationUnit(tu); - translationUnits_.erase(it++); // post-increment keeps the iterator valid - } else { - ++it; - } - } -} diff --git a/elpa/irony-20220110.849/server/src/TUManager.h b/elpa/irony-20220110.849/server/src/TUManager.h deleted file mode 100644 index bd7730d..0000000 --- a/elpa/irony-20220110.849/server/src/TUManager.h +++ /dev/null @@ -1,109 +0,0 @@ -/**-*-C++-*- - * \file - * \author Guillaume Papin <guillaume.papin@epitech.eu> - * - * \brief Translation Unit manager. - * - * Keeps a cache of translation units, reparsing or recreating them as - * necessary. - * - * This file is distributed under the GNU General Public License. See - * COPYING for details. - */ - -#ifndef IRONY_MODE_SERVER_TUMANAGER_H_ -#define IRONY_MODE_SERVER_TUMANAGER_H_ - -#include "support/CIndex.h" -#include "support/NonCopyable.h" - -#include <map> -#include <string> -#include <vector> - -class TUManager : public util::NonCopyable { -public: - TUManager(); - ~TUManager(); - - /** - * \brief Parse \p filename with flag \p flags. - * - * The first time call \c clang_parseTranslationUnit() and save the TU in the - * member \c translationUnits_, The next call with the same \p filename will - * call \c clang_reparseTranslationUnit(). - * - * usage: - * \code - * std::vector<std::string> flags; - * flags.push_back("-I../utils"); - * CXTranslationUnit tu = tuManager.parse("file.cpp", flags); - * - * if (! tu) - * std::cerr << "parsing translation unit failed\n"; - * \endcode - * - * \return The translation unit, if the parsing failed the translation unit - * will be \c NULL. - */ - CXTranslationUnit parse(const std::string &filename, - const std::vector<std::string> &flags, - const std::vector<CXUnsavedFile> &unsavedFiles); - - /** - * \brief Retrieve, creating it if necessary the TU associated to filename. - * - * \return The translation unit. Will be NULL if the translation unit couldn't - * be created. - */ - CXTranslationUnit getOrCreateTU(const std::string &filename, - const std::vector<std::string> &flags, - const std::vector<CXUnsavedFile> &unsavedFiles); - - /** - * \brief Invalidate a given cached TU, the next use of a TU will require - * reparsing. - * - * This can be useful for example: when the flags used to compile a file have - * changed. - * - * \param filename The filename for which the associated - * translation unit flags need to be invalidated. - * - * \sa invalidateAllCachedTUs() - */ - void invalidateCachedTU(const std::string &filename); - - /** - * \brief Invalidate all cached TU, the next use of a TU will require - * reparsing. - * - * \sa invalidateCachedTU() - */ - void invalidateAllCachedTUs(); - -private: - /** - * \brief Get a reference to the translation unit that matches \p filename - * with the given set of flags. - * - * The TU will be null if it has never been parsed or if the flags have - * changed. - * - * \todo Find a proper name. - */ - CXTranslationUnit &tuRef(const std::string &filename, - const std::vector<std::string> &flags); - -private: - typedef std::map<const std::string, CXTranslationUnit> TranslationUnitsMap; - typedef std::map<const std::string, std::vector<std::string>> FilenameFlagsMap; - -private: - CXIndex index_; - TranslationUnitsMap translationUnits_; // cache variable - FilenameFlagsMap flagsPerFileCache_; - unsigned parseTUOptions_; -}; - -#endif /* !IRONY_MODE_SERVER_TUMANAGER_H_ */ diff --git a/elpa/irony-20220110.849/server/src/main.cpp b/elpa/irony-20220110.849/server/src/main.cpp deleted file mode 100644 index 7797528..0000000 --- a/elpa/irony-20220110.849/server/src/main.cpp +++ /dev/null @@ -1,235 +0,0 @@ -/** - * \file - * \author Guillaume Papin <guillaume.papin@epitech.eu> - * - * This file is distributed under the GNU General Public License. See - * COPYING for details. - */ - -#include "Irony.h" -#include "Command.h" - -#include "support/CIndex.h" -#include "support/CommandLineParser.h" - -#include <cassert> -#include <cstdlib> -#include <fstream> -#include <iomanip> -#include <iostream> -#include <iterator> -#include <memory> -#include <vector> - -static void printHelp() { - std::cout << "usage: irony-server [OPTIONS...] [COMMAND] [ARGS...]\n" - "\n" - "Options:\n" - " -v, --version\n" - " -h, --help\n" - " -i, --interactive\n" - " -d, --debug\n" - " --log-file PATH\n" - "\n" - "Commands:\n"; - -#define X(sym, str, desc) \ - if (Command::sym != Command::Unknown) \ - std::cout << std::left << std::setw(25) << " " str << desc << "\n"; -#include "Commands.def" -} - -static void printVersion() { - // do not change the format for the first line, external programs should be - // able to rely on it - std::cout << "irony-server version " IRONY_PACKAGE_VERSION "\n"; - - CXString cxVersionString = clang_getClangVersion(); - std::cout << clang_getCString(cxVersionString) << "\n"; - clang_disposeString(cxVersionString); -} - -struct CommandProviderInterface { - virtual ~CommandProviderInterface() { } - - virtual std::vector<std::string> nextCommand() = 0; -}; - -struct CommandLineCommandProvider : CommandProviderInterface { - CommandLineCommandProvider(const std::vector<std::string> &argv) - : argv_(argv), firstCall_(true) { - } - - std::vector<std::string> nextCommand() { - if (firstCall_) { - firstCall_ = false; - return argv_; - } - - return std::vector<std::string>(1, "exit"); - } - -private: - std::vector<std::string> argv_; - bool firstCall_; -}; - -struct InteractiveCommandProvider : CommandProviderInterface { - std::vector<std::string> nextCommand() { - std::string line; - - if (std::getline(std::cin, line)) { - return unescapeCommandLine(line); - } - - return std::vector<std::string>(1, "exit"); - } -}; - -struct RestoreClogOnExit { - RestoreClogOnExit() : rdbuf_(std::clog.rdbuf()) { - } - - ~RestoreClogOnExit() { - std::clog.rdbuf(rdbuf_); - } - -private: - RestoreClogOnExit(const RestoreClogOnExit &); - RestoreClogOnExit &operator=(const RestoreClogOnExit &); - -private: - std::streambuf *rdbuf_; -}; - -int main(int ac, const char *av[]) { - std::vector<std::string> argv(&av[1], &av[ac]); - - // stick to STL streams, no mix of C and C++ for IO operations - std::ios_base::sync_with_stdio(false); - - bool interactiveMode = false; - - Irony irony; - - if (ac == 1) { - printHelp(); - return 1; - } - - std::ofstream logFile; - - // When logging to a specific file, std::clog.rdbuf() is replaced by the log - // file's one. When we return from the main, this buffer is deleted (at the - // same time as logFile) but std::clog is still active, and will try to - // release the rdbuf() which has already been released in logFile's - // destructor. To avoid this we restore std::clog()'s original rdbuf on exit. - RestoreClogOnExit clogBufferRestorer; - - unsigned optCount = 0; - while (optCount < argv.size()) { - const std::string &opt = argv[optCount]; - - if (opt.c_str()[0] != '-') - break; - - if (opt == "--help" || opt == "-h") { - printHelp(); - return 0; - } - - if (opt == "--version" || opt == "-v") { - printVersion(); - return 0; - } - - if (opt == "--interactive" || opt == "-i") { - interactiveMode = true; - } else if (opt == "--debug" || opt == "-d") { - irony.setDebug(true); - } else if (opt == "--log-file" && (optCount + 1) < argv.size()) { - ++optCount; - logFile.open(argv[optCount]); - std::clog.rdbuf(logFile.rdbuf()); - } else { - std::cerr << "error: invalid option '" << opt << "'\n"; - return 1; - } - - ++optCount; - } - - argv.erase(argv.begin(), argv.begin() + optCount); - - CommandParser commandParser; - std::unique_ptr<CommandProviderInterface> commandProvider; - - if (interactiveMode) { - commandProvider.reset(new InteractiveCommandProvider()); - } else { - commandProvider.reset(new CommandLineCommandProvider(argv)); - } - - while (Command *c = commandParser.parse(commandProvider->nextCommand())) { - if (c->action != Command::Exit) { - std::clog << "execute: " << *c << std::endl; - } - - switch (c->action) { - case Command::Help: - printHelp(); - break; - - case Command::Candidates: - irony.candidates(c->prefix, c->style); - break; - - case Command::CompletionDiagnostics: - irony.completionDiagnostics(); - break; - - case Command::Complete: - irony.complete(c->file, c->line, c->column, c->flags); - break; - - case Command::Diagnostics: - irony.diagnostics(); - break; - - case Command::Exit: - return 0; - - case Command::GetCompileOptions: - irony.getCompileOptions(c->dir, c->file); - break; - - case Command::GetType: - irony.getType(c->line, c->column); - break; - - case Command::Parse: - irony.parse(c->file, c->flags); - break; - - case Command::SetDebug: - irony.setDebug(c->opt); - break; - - case Command::SetUnsaved: - irony.setUnsaved(c->file, c->unsavedFile); - break; - - case Command::ResetUnsaved: - irony.resetUnsaved(c->file); - break; - - case Command::Unknown: - assert(0 && "unreacheable code...reached!"); - break; - } - - std::cout << "\n;;EOT\n" << std::flush; - } - - return 1; -} diff --git a/elpa/irony-20220110.849/server/src/support/CIndex.h b/elpa/irony-20220110.849/server/src/support/CIndex.h deleted file mode 100644 index 89d3f62..0000000 --- a/elpa/irony-20220110.849/server/src/support/CIndex.h +++ /dev/null @@ -1,33 +0,0 @@ -/** - * \file - * \brief Wrapper around Clang Indexing Public C Interface header. - * - * This file is distributed under the GNU General Public License. See - * COPYING for details. - */ - -#ifndef IRONY_MODE_SERVER_SUPPORT_CINDEXVERSION_H_ -#define IRONY_MODE_SERVER_SUPPORT_CINDEXVERSION_H_ - -#include <clang-c/Index.h> - -/// Use <tt>\#if CINDEX_VERSION_VERSION > 10047</tt> to test for -/// CINDEX_VERSION_MAJOR = 1 and CINDEX_VERSION_MINOR = 47. -#ifndef CINDEX_VERSION -#define CINDEX_VERSION 0 // pre-clang 3.2 support -#endif - -#if CINDEX_VERSION >= 6 -#define HAS_BRIEF_COMMENTS_IN_COMPLETION 1 -#else -#define HAS_BRIEF_COMMENTS_IN_COMPLETION 0 -#endif - -#if CINDEX_VERSION >= 6 -#define HAS_COMPILATION_DATABASE 1 -#include <clang-c/CXCompilationDatabase.h> -#else -#define HAS_COMPILATION_DATABASE 0 -#endif - -#endif /* !IRONY_MODE_SERVER_SUPPORT_CINDEXVERSION_H_ */ diff --git a/elpa/irony-20220110.849/server/src/support/CommandLineParser.cpp b/elpa/irony-20220110.849/server/src/support/CommandLineParser.cpp deleted file mode 100644 index a838092..0000000 --- a/elpa/irony-20220110.849/server/src/support/CommandLineParser.cpp +++ /dev/null @@ -1,119 +0,0 @@ -/** - * \file - * \author Guillaume Papin <guillaume.papin@epitech.eu> - * - * This file is distributed under the GNU General Public License. See - * COPYING for details. - */ - -#include "CommandLineParser.h" - -namespace { - -/// \brief A parser for escaped strings of command line arguments. -/// -/// Assumes \-escaping for quoted arguments (see the documentation of -/// unescapeCommandLine(...)). -class CommandLineArgumentParser { -public: - CommandLineArgumentParser(const std::string &commandLine) - : input_(commandLine), position_(input_.begin() - 1) { - } - - std::vector<std::string> parse() { - bool hasMoreInput = true; - while (hasMoreInput && nextNonWhitespace()) { - std::string argument; - hasMoreInput = parseStringInto(argument); - commandLine_.push_back(argument); - } - return commandLine_; - } - -private: - // All private methods return true if there is more input available. - - bool parseStringInto(std::string &string) { - do { - if (*position_ == '"') { - if (!parseDoubleQuotedStringInto(string)) - return false; - } else if (*position_ == '\'') { - if (!parseSingleQuotedStringInto(string)) - return false; - } else { - if (!parseFreeStringInto(string)) - return false; - } - } while (*position_ != ' '); - return true; - } - - bool parseDoubleQuotedStringInto(std::string &string) { - if (!next()) - return false; - while (*position_ != '"') { - if (!skipEscapeCharacter()) - return false; - string.push_back(*position_); - if (!next()) - return false; - } - return next(); - } - - bool parseSingleQuotedStringInto(std::string &string) { - if (!next()) - return false; - while (*position_ != '\'') { - string.push_back(*position_); - if (!next()) - return false; - } - return next(); - } - - bool parseFreeStringInto(std::string &string) { - do { - if (!skipEscapeCharacter()) - return false; - string.push_back(*position_); - if (!next()) - return false; - } while (*position_ != ' ' && *position_ != '"' && *position_ != '\''); - return true; - } - - bool skipEscapeCharacter() { - if (*position_ == '\\') { - return next(); - } - return true; - } - - bool nextNonWhitespace() { - do { - if (!next()) - return false; - } while (*position_ == ' '); - return true; - } - - bool next() { - ++position_; - return position_ != input_.end(); - } - -private: - const std::string input_; - std::string::const_iterator position_; - std::vector<std::string> commandLine_; -}; - -} // unnamed namespace - -std::vector<std::string> -unescapeCommandLine(const std::string &escapedCommandLine) { - CommandLineArgumentParser parser(escapedCommandLine); - return parser.parse(); -} diff --git a/elpa/irony-20220110.849/server/src/support/CommandLineParser.h b/elpa/irony-20220110.849/server/src/support/CommandLineParser.h deleted file mode 100644 index b764797..0000000 --- a/elpa/irony-20220110.849/server/src/support/CommandLineParser.h +++ /dev/null @@ -1,21 +0,0 @@ -/** - * \file - * \brief Facility to parse a command line into a string array. - * - * \note Please note that the code borrowed from the Clang, - * lib/Tooling/JSONCompilationDatabase.cpp. - * - * This file is distributed under the GNU General Public License. See - * COPYING for details. - */ - -#ifndef IRONY_MODE_SERVER_SUPPORT_COMMAND_LINE_PARSER_H_ -#define IRONY_MODE_SERVER_SUPPORT_COMMAND_LINE_PARSER_H_ - -#include <string> -#include <vector> - -std::vector<std::string> -unescapeCommandLine(const std::string &escapedCommandLine); - -#endif // IRONY_MODE_SERVER_SUPPORT_COMMAND_LINE_PARSER_H_ diff --git a/elpa/irony-20220110.849/server/src/support/NonCopyable.h b/elpa/irony-20220110.849/server/src/support/NonCopyable.h deleted file mode 100644 index d30a5b2..0000000 --- a/elpa/irony-20220110.849/server/src/support/NonCopyable.h +++ /dev/null @@ -1,34 +0,0 @@ -/**-*-C++-*- - * \file - * \author Guillaume Papin <guillaume.papin@epitech.eu> - * - * \brief NonCopyable class like in Boost. - * - * \see http://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Non-copyable_Mixin - * - * This file is distributed under the GNU General Public License. See - * COPYING for details. - */ - -#ifndef IRONY_MODE_SERVER_SUPPORT_NONCOPYABLE_H_ -#define IRONY_MODE_SERVER_SUPPORT_NONCOPYABLE_H_ - -namespace util { - -class NonCopyable { -protected: - NonCopyable() { - } - - // Protected non-virtual destructor - ~NonCopyable() { - } - -private: - NonCopyable(const NonCopyable &); - NonCopyable &operator=(const NonCopyable &); -}; - -} // ! namespace util - -#endif /* !IRONY_MODE_SERVER_SUPPORT_NONCOPYABLE_H_ */ diff --git a/elpa/irony-20220110.849/server/src/support/TemporaryFile.cpp b/elpa/irony-20220110.849/server/src/support/TemporaryFile.cpp deleted file mode 100644 index e7393e1..0000000 --- a/elpa/irony-20220110.849/server/src/support/TemporaryFile.cpp +++ /dev/null @@ -1,74 +0,0 @@ -/** - * \file - * \author Guillaume Papin <guillaume.papin@epitech.eu> - * - * This file is distributed under the GNU General Public License. See - * COPYING for details. - */ - -#include "TemporaryFile.h" - -#include <algorithm> -#include <cstdio> -#include <cstdlib> -#include <fstream> -#include <iostream> -#include <random> - -static std::string getTemporaryFileDirectory() { - const char *temporaryDirEnvVars[] = {"TMPDIR", "TMP", "TEMP", "TEMPDIR"}; - - for (const char *envVar : temporaryDirEnvVars) { - if (const char *dir = std::getenv(envVar)) - return dir; - } - - return "/tmp"; -} - -TemporaryFile::TemporaryFile(const std::string &prefix, - const std::string &suffix) - : pathOrPattern_(prefix + "-%%%%%%" + suffix) { -} - -TemporaryFile::~TemporaryFile() { - if (openedFile_) { - openedFile_.reset(); - std::remove(pathOrPattern_.c_str()); - } -} - -const std::string &TemporaryFile::getPath() { - if (!openedFile_) { - openedFile_.reset(new std::fstream); - - std::random_device rd; - std::default_random_engine e(rd()); - std::uniform_int_distribution<int> dist(0, 15); - std::string pattern = pathOrPattern_; - std::string tmpDir = getTemporaryFileDirectory() + "/"; - int i = 0; - - do { - // exiting is better than infinite loop - if (++i > TemporaryFile::MAX_ATTEMPS) { - std::cerr << "error: couldn't create temporary file, please check your " - "temporary file directory (" << tmpDir << ")\n"; - exit(EXIT_FAILURE); - } - - // make the filename based on the pattern - std::transform(pattern.begin(), - pattern.end(), - pathOrPattern_.begin(), - [&e, &dist](char ch) { - return ch == '%' ? "0123456789abcdef"[dist(e)] : ch; - }); - // create the file - openedFile_->open(tmpDir + pathOrPattern_, std::ios_base::out); - } while (!openedFile_->is_open()); - pathOrPattern_ = tmpDir + pathOrPattern_; - } - - return pathOrPattern_; -} diff --git a/elpa/irony-20220110.849/server/src/support/TemporaryFile.h b/elpa/irony-20220110.849/server/src/support/TemporaryFile.h deleted file mode 100644 index 5bf77f4..0000000 --- a/elpa/irony-20220110.849/server/src/support/TemporaryFile.h +++ /dev/null @@ -1,36 +0,0 @@ -/**-*-C++-*- - * \file - * \author Guillaume Papin <guillaume.papin@epitech.eu> - * - * \brief Not the best piece of code out there. - * - * This file is distributed under the GNU General Public License. See - * COPYING for details. - */ - -#ifndef IRONY_MODE_SERVER_SUPPORT_TEMPORARY_FILE_H_ -#define IRONY_MODE_SERVER_SUPPORT_TEMPORARY_FILE_H_ - -#include <iosfwd> -#include <memory> -#include <string> - -class TemporaryFile { - enum { - // if we can't create the temp file, exits. - MAX_ATTEMPS = 25 - }; - -public: - TemporaryFile(const std::string &prefix, const std::string &suffix = ""); - ~TemporaryFile(); - - /// Returns the path of this temporary filename - const std::string &getPath(); - -private: - std::string pathOrPattern_; - std::unique_ptr<std::fstream> openedFile_; -}; - -#endif // IRONY_MODE_SERVER_SUPPORT_TEMPORARY_FILE_H_ diff --git a/elpa/irony-20220110.849/server/src/support/iomanip_quoted.h b/elpa/irony-20220110.849/server/src/support/iomanip_quoted.h deleted file mode 100644 index a8ca38b..0000000 --- a/elpa/irony-20220110.849/server/src/support/iomanip_quoted.h +++ /dev/null @@ -1,52 +0,0 @@ -/**-*-C++-*- - * \file - * \brief Dumb implementation of something that might look like C++14 - * std::quoted. - * - * This file is distributed under the GNU General Public License. See - * COPYING for details. - */ - -#ifndef IRONY_MODE_SERVER_SUPPORT_IOMANIP_QUOTED_H_ -#define IRONY_MODE_SERVER_SUPPORT_IOMANIP_QUOTED_H_ - -#include <ostream> -#include <string> - -namespace support { -namespace detail { - -struct QuotedStringProxy { - QuotedStringProxy(const std::string &s) : s(s) { - } - - std::string s; -}; - -std::ostream &operator<<(std::ostream &os, const QuotedStringProxy &q) { - const std::string &s = q.s; - - os << '"'; - if (s.find_first_of("\"\\") == std::string::npos) { - os << s; - } else { - for (auto ch : s) { - if (ch == '\\' || ch == '"') - os << '\\'; - - os << ch; - } - } - os << '"'; - return os; -} - -} // namespace detail - -detail::QuotedStringProxy quoted(const std::string &s) { - return detail::QuotedStringProxy(s); -} - -} // namespace support - -#endif // IRONY_MODE_SERVER_SUPPORT_IOMANIP_QUOTED_H_ |