• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //===--- Config.h - User configuration of clangd behavior --------*- C++-*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // Various clangd features have configurable behaviour (or can be disabled).
10 // This file defines "resolved" configuration seen by features within clangd.
11 // For example, settings may vary per-file, the resolved Config only contains
12 // settings that apply to the current file.
13 //
14 // This is distinct from how the config is specified by the user (Fragment)
15 // interpreted (CompiledFragment), and combined (Provider).
16 // ConfigFragment.h describes the steps to add a new configuration option.
17 //
18 // Because this structure is shared throughout clangd, it's a potential source
19 // of layering problems. Config should be expressed in terms of simple
20 // vocubulary types where possible.
21 //
22 //===----------------------------------------------------------------------===//
23 
24 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_CONFIG_H
25 #define LLVM_CLANG_TOOLS_EXTRA_CLANGD_CONFIG_H
26 
27 #include "support/Context.h"
28 #include "llvm/ADT/FunctionExtras.h"
29 #include "llvm/ADT/Optional.h"
30 #include "llvm/ADT/StringMap.h"
31 #include <string>
32 #include <vector>
33 
34 namespace clang {
35 namespace clangd {
36 
37 /// Settings that express user/project preferences and control clangd behavior.
38 ///
39 /// Generally, features should consume Config::current() and the caller is
40 /// responsible for setting it appropriately. In practice these callers are
41 /// ClangdServer, TUScheduler, and BackgroundQueue.
42 struct Config {
43   /// Returns the Config of the current Context, or an empty configuration.
44   static const Config &current();
45   /// Context key which can be used to set the current Config.
46   static clangd::Key<Config> Key;
47 
48   Config() = default;
49   Config(const Config &) = delete;
50   Config &operator=(const Config &) = delete;
51   Config(Config &&) = default;
52   Config &operator=(Config &&) = default;
53 
54   /// Controls how the compile command for the current file is determined.
55   struct {
56     // Edits to apply to the compile command, in sequence.
57     std::vector<llvm::unique_function<void(std::vector<std::string> &) const>>
58         Edits;
59   } CompileFlags;
60 
61   enum class BackgroundPolicy { Build, Skip };
62   /// Describes an external index configuration.
63   struct ExternalIndexSpec {
64     enum { File, Server } Kind;
65     /// This is one of:
66     /// - Address of a clangd-index-server, in the form of "ip:port".
67     /// - Absolute path to an index produced by clangd-indexer.
68     std::string Location;
69     /// Absolute path to source root this index is associated with, uses
70     /// forward-slashes.
71     std::string MountPoint;
72   };
73   /// Controls background-index behavior.
74   struct {
75     /// Whether this TU should be indexed.
76     BackgroundPolicy Background = BackgroundPolicy::Build;
77     llvm::Optional<ExternalIndexSpec> External;
78   } Index;
79 
80   /// Style of the codebase.
81   struct {
82     // Namespaces that should always be fully qualified, meaning no "using"
83     // declarations, always spell out the whole name (with or without leading
84     // ::). All nested namespaces are affected as well.
85     std::vector<std::string> FullyQualifiedNamespaces;
86   } Style;
87 
88   /// Configures what clang-tidy checks to run and options to use with them.
89   struct {
90     // A comma-seperated list of globs to specify which clang-tidy checks to
91     // run.
92     std::string Checks;
93     llvm::StringMap<std::string> CheckOptions;
94   } ClangTidy;
95 };
96 
97 } // namespace clangd
98 } // namespace clang
99 
100 namespace llvm {
101 template <> struct DenseMapInfo<clang::clangd::Config::ExternalIndexSpec> {
102   using ExternalIndexSpec = clang::clangd::Config::ExternalIndexSpec;
103   static inline ExternalIndexSpec getEmptyKey() {
104     return {ExternalIndexSpec::File, "", ""};
105   }
106   static inline ExternalIndexSpec getTombstoneKey() {
107     return {ExternalIndexSpec::File, "TOMB", "STONE"};
108   }
109   static unsigned getHashValue(const ExternalIndexSpec &Val) {
110     return llvm::hash_combine(Val.Kind, Val.Location, Val.MountPoint);
111   }
112   static bool isEqual(const ExternalIndexSpec &LHS,
113                       const ExternalIndexSpec &RHS) {
114     return std::tie(LHS.Kind, LHS.Location, LHS.MountPoint) ==
115            std::tie(RHS.Kind, RHS.Location, RHS.MountPoint);
116   }
117 };
118 } // namespace llvm
119 
120 #endif
121