2018-08-21 05:27:52 +00:00
|
|
|
/* Copyright 2017-2018 ccls Authors
|
|
|
|
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
you may not use this file except in compliance with the License.
|
|
|
|
You may obtain a copy of the License at
|
|
|
|
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
See the License for the specific language governing permissions and
|
|
|
|
limitations under the License.
|
|
|
|
==============================================================================*/
|
|
|
|
|
2017-03-26 06:47:59 +00:00
|
|
|
#pragma once
|
|
|
|
|
2018-10-28 17:49:31 +00:00
|
|
|
#include "lsp.hh"
|
2018-10-29 04:21:21 +00:00
|
|
|
#include "utils.hh"
|
2017-03-26 06:47:59 +00:00
|
|
|
|
2017-05-10 04:52:15 +00:00
|
|
|
#include <mutex>
|
2018-07-15 07:45:51 +00:00
|
|
|
#include <optional>
|
2017-03-26 21:40:34 +00:00
|
|
|
#include <string>
|
|
|
|
|
2018-10-28 17:49:31 +00:00
|
|
|
namespace ccls {
|
2017-04-16 08:09:12 +00:00
|
|
|
struct WorkingFile {
|
2017-04-14 08:21:03 +00:00
|
|
|
int version = 0;
|
2017-03-26 21:40:34 +00:00
|
|
|
std::string filename;
|
|
|
|
|
2017-04-16 08:09:12 +00:00
|
|
|
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).
|
2018-01-14 18:50:54 +00:00
|
|
|
std::vector<std::string> buffer_lines;
|
2018-01-13 19:39:06 +00:00
|
|
|
// Mappings between index line number and buffer line number.
|
2018-01-14 21:24:52 +00:00
|
|
|
// 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.
|
2018-01-13 19:39:06 +00:00
|
|
|
std::vector<int> index_to_buffer;
|
|
|
|
std::vector<int> buffer_to_index;
|
2017-05-20 19:31:07 +00:00
|
|
|
// 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!
|
2018-11-03 20:52:43 +00:00
|
|
|
std::vector<Diagnostic> diagnostics_;
|
2017-04-19 07:52:48 +00:00
|
|
|
|
2018-08-09 17:08:14 +00:00
|
|
|
WorkingFile(const std::string &filename, const std::string &buffer_content);
|
2017-04-09 19:38:52 +00:00
|
|
|
|
2017-04-16 08:09:12 +00:00
|
|
|
// 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);
|
2017-04-16 08:09:12 +00:00
|
|
|
// This should be called whenever |buffer_content| has changed.
|
|
|
|
void OnBufferContentUpdated();
|
2017-04-09 19:38:52 +00:00
|
|
|
|
2018-01-14 22:24:47 +00:00
|
|
|
// Finds the buffer line number which maps to index line number |line|.
|
|
|
|
// Also resolves |column| if not NULL.
|
2018-01-15 01:16:24 +00:00
|
|
|
// 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);
|
2018-01-14 22:24:47 +00:00
|
|
|
// 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-05-20 08:07:29 +00:00
|
|
|
// 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.
|
2017-06-16 02:28:49 +00:00
|
|
|
// The out param |existing_completion| is set to any existing completion
|
|
|
|
// content the user has entered.
|
2018-11-04 18:30:18 +00:00
|
|
|
Position FindStableCompletionSource(Position position,
|
2018-08-09 17:08:14 +00:00
|
|
|
std::string *existing_completion,
|
2018-11-04 18:30:18 +00:00
|
|
|
Position *replace_end_pos) const;
|
2018-01-13 19:39:06 +00:00
|
|
|
|
2018-08-09 17:08:14 +00:00
|
|
|
private:
|
2018-01-13 19:39:06 +00:00
|
|
|
// Compute index_to_buffer and buffer_to_index.
|
|
|
|
void ComputeLineMapping();
|
2018-01-06 05:45:20 +00:00
|
|
|
};
|
2017-05-20 08:07:29 +00:00
|
|
|
|
2018-01-12 17:37:33 +00:00
|
|
|
struct WorkingFiles {
|
|
|
|
struct Snapshot {
|
|
|
|
struct File {
|
|
|
|
std::string filename;
|
|
|
|
std::string content;
|
|
|
|
};
|
|
|
|
|
|
|
|
std::vector<File> files;
|
2018-01-06 05:45:20 +00:00
|
|
|
};
|
2017-03-26 21:40:34 +00:00
|
|
|
|
2017-05-10 04:52:15 +00:00
|
|
|
//
|
|
|
|
// :: IMPORTANT :: All methods in this class are guarded by a single lock.
|
|
|
|
//
|
|
|
|
|
2017-03-26 21:40:34 +00:00
|
|
|
// 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);
|
2018-08-28 05:42:40 +00:00
|
|
|
std::string GetContent(const std::string &filename);
|
2017-05-10 04:52:15 +00:00
|
|
|
|
2017-06-14 06:29:41 +00:00
|
|
|
// Run |action| under the lock.
|
2018-11-17 18:23:12 +00:00
|
|
|
template <typename Fn> void DoAction(Fn &&fn) {
|
|
|
|
std::lock_guard<std::mutex> lock(files_mutex);
|
|
|
|
fn();
|
|
|
|
}
|
2017-06-14 06:29:41 +00:00
|
|
|
|
2018-11-03 20:52:43 +00:00
|
|
|
WorkingFile *OnOpen(const TextDocumentItem &open);
|
2018-10-28 17:49:31 +00:00
|
|
|
void OnChange(const TextDocumentDidChangeParam &change);
|
2018-11-03 20:52:43 +00:00
|
|
|
void OnClose(const TextDocumentIdentifier &close);
|
2017-03-26 21:40:34 +00:00
|
|
|
|
|
|
|
// 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|.
|
2017-12-25 08:58:26 +00:00
|
|
|
};
|
2018-06-01 03:06:09 +00:00
|
|
|
|
2018-11-04 18:30:18 +00:00
|
|
|
int GetOffsetForPosition(Position pos, std::string_view content);
|
2018-06-01 03:06:09 +00:00
|
|
|
|
2018-11-04 18:30:18 +00:00
|
|
|
std::string_view LexIdentifierAroundPos(Position position,
|
2018-06-01 03:06:09 +00:00
|
|
|
std::string_view content);
|
2018-10-28 17:49:31 +00:00
|
|
|
} // namespace ccls
|