ccls/src/working_files.h

123 lines
4.7 KiB
C
Raw Normal View History

#pragma once
#include "lsp_diagnostic.h"
#include "utils.h"
#include <mutex>
2018-07-15 07:45:51 +00:00
#include <optional>
#include <string>
struct WorkingFile {
int version = 0;
std::string filename;
std::string buffer_content;
// Note: This assumes 0-based lines (1-based lines are normally assumed).
std::vector<std::string> index_lines;
// Note: This assumes 0-based lines (1-based lines are normally assumed).
std::vector<std::string> buffer_lines;
// Mappings between index line number and buffer line number.
// Empty indicates either buffer or index has been changed and re-computation
// is required.
// For index_to_buffer[i] == j, if j >= 0, we are confident that index line
// i maps to buffer line j; if j == -1, FindMatchingLine will use the nearest
// confident lines to resolve its line number.
std::vector<int> index_to_buffer;
std::vector<int> buffer_to_index;
// A set of diagnostics that have been reported for this file.
2017-09-22 01:14:57 +00:00
// NOTE: _ is appended because it must be accessed under the WorkingFiles
// lock!
std::vector<lsDiagnostic> diagnostics_;
2018-08-09 17:08:14 +00:00
WorkingFile(const std::string &filename, const std::string &buffer_content);
// This should be called when the indexed content has changed.
2018-08-09 17:08:14 +00:00
void SetIndexContent(const std::string &index_content);
// This should be called whenever |buffer_content| has changed.
void OnBufferContentUpdated();
// Finds the buffer line number which maps to index line number |line|.
// Also resolves |column| if not NULL.
// When resolving a range, use is_end = false for begin() and is_end =
// true for end() to get a better alignment of |column|.
2018-08-09 17:08:14 +00:00
std::optional<int> GetBufferPosFromIndexPos(int line, int *column,
bool is_end);
// Finds the index line number which maps to buffer line number |line|.
// Also resolves |column| if not NULL.
2018-08-09 17:08:14 +00:00
std::optional<int> GetIndexPosFromBufferPos(int line, int *column,
bool is_end);
2017-09-22 01:14:57 +00:00
// TODO: Move FindClosestCallNameInBuffer and FindStableCompletionSource into
// lex_utils.h/cc
2017-06-15 05:32:23 +00:00
// Finds the closest 'callable' name prior to position. This is used for
// signature help to filter code completion results.
//
// |completion_position| will be point to a good code completion location to
// for fetching signatures.
2018-08-09 17:08:14 +00:00
std::string
FindClosestCallNameInBuffer(lsPosition position, int *active_parameter,
lsPosition *completion_position = nullptr) const;
// Returns a relatively stable completion position (it jumps back until there
// is a non-alphanumeric character).
2017-05-26 07:10:55 +00:00
//
// The out param |is_global_completion| is set to true if this looks like a
// global completion.
// The out param |existing_completion| is set to any existing completion
// content the user has entered.
2017-09-22 01:14:57 +00:00
lsPosition FindStableCompletionSource(lsPosition position,
2018-08-09 17:08:14 +00:00
bool *is_global_completion,
std::string *existing_completion,
lsPosition *replace_end_pos) const;
2018-08-09 17:08:14 +00:00
private:
// Compute index_to_buffer and buffer_to_index.
void ComputeLineMapping();
};
struct WorkingFiles {
struct Snapshot {
struct File {
std::string filename;
std::string content;
};
std::vector<File> files;
};
//
// :: IMPORTANT :: All methods in this class are guarded by a single lock.
//
// Find the file with the given filename.
2018-08-09 17:08:14 +00:00
WorkingFile *GetFileByFilename(const std::string &filename);
WorkingFile *GetFileByFilenameNoLock(const std::string &filename);
// Run |action| under the lock.
2018-08-09 17:08:14 +00:00
void DoAction(const std::function<void()> &action);
2017-09-22 01:14:57 +00:00
// Run |action| on the file identified by |filename|. This executes under the
// lock.
2018-08-09 17:08:14 +00:00
void DoActionOnFile(const std::string &filename,
const std::function<void(WorkingFile *file)> &action);
2018-08-09 17:08:14 +00:00
WorkingFile *OnOpen(const lsTextDocumentItem &open);
void OnChange(const lsTextDocumentDidChangeParams &change);
void OnClose(const lsTextDocumentIdentifier &close);
// If |filter_paths| is non-empty, only files which contain any of the given
// strings. For example, {"foo", "bar"} means that every result has either the
// string "foo" or "bar" contained within it.
2018-08-09 17:08:14 +00:00
Snapshot AsSnapshot(const std::vector<std::string> &filter_paths);
// Use unique_ptrs so we can handout WorkingFile ptrs and not have them
// invalidated if we resize files.
std::vector<std::unique_ptr<WorkingFile>> files;
2018-08-09 17:08:14 +00:00
std::mutex files_mutex; // Protects |files|.
};
int GetOffsetForPosition(lsPosition position, std::string_view content);
std::string_view LexIdentifierAroundPos(lsPosition position,
std::string_view content);