1 // Copyright 2017-2018 ccls Authors
2 // SPDX-License-Identifier: Apache-2.0
3 
4 #pragma once
5 
6 #include "config.hh"
7 #include "lsp.hh"
8 
9 #include <functional>
10 #include <mutex>
11 #include <string>
12 #include <unordered_map>
13 #include <vector>
14 
15 namespace ccls {
16 struct WorkingFiles;
17 
18 std::pair<LanguageId, bool> lookupExtension(std::string_view filename);
19 
20 struct Project {
21   struct Entry {
22     std::string root;
23     std::string directory;
24     std::string filename;
25     std::vector<const char *> args;
26     // If true, this entry is inferred and was not read from disk.
27     bool is_inferred = false;
28     // 0 unless coming from a compile_commands.json entry.
29     int compdb_size = 0;
30     int id = -1;
31   };
32 
33   struct Folder {
34     std::string name;
35     std::unordered_map<std::string, int> search_dir2kind;
36     std::vector<Entry> entries;
37     std::unordered_map<std::string, int> path2entry_index;
38     std::unordered_map<std::string, std::vector<const char *>> dot_ccls;
39   };
40 
41   std::mutex mtx;
42   std::unordered_map<std::string, Folder> root2folder;
43 
44   // Loads a project for the given |directory|.
45   //
46   // If |config->compilationDatabaseDirectory| is not empty, look for .ccls or
47   // compile_commands.json in it, otherwise they are retrieved in
48   // |root_directory|.
49   // For .ccls, recursive directory listing is used and files with known
50   // suffixes are indexed. .ccls files can exist in subdirectories and they
51   // will affect flags in their subtrees (relative paths are relative to the
52   // project root, not subdirectories). For compile_commands.json, its entries
53   // are indexed.
54   void load(const std::string &root);
55   void loadDirectory(const std::string &root, Folder &folder);
56 
57   // Lookup the CompilationEntry for |filename|. If no entry was found this
58   // will infer one based on existing project structure.
59   Entry findEntry(const std::string &path, bool can_redirect, bool must_exist);
60 
61   // If the client has overridden the flags, or specified them for a file
62   // that is not in the compilation_database.json make sure those changes
63   // are permanent.
64   void setArgsForFile(const std::vector<const char *> &args,
65                       const std::string &path);
66 
67   void index(WorkingFiles *wfiles, const RequestId &id);
68   void indexRelated(const std::string &path);
69 };
70 } // namespace ccls
71