[docs] Add LICENSE.txt to the root of the mono-repo
[llvm-project.git] / clang-tools-extra / clangd / IncludeFixer.h
blob2bb6c229f4677368bb4e879124dbdd83937d803b
1 //===--- IncludeFixer.h ------------------------------------------*- 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 //===----------------------------------------------------------------------===//
9 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_INCLUDEFIXER_H
10 #define LLVM_CLANG_TOOLS_EXTRA_CLANGD_INCLUDEFIXER_H
12 #include "Diagnostics.h"
13 #include "Headers.h"
14 #include "index/Index.h"
15 #include "index/Symbol.h"
16 #include "clang/AST/Type.h"
17 #include "clang/Basic/Diagnostic.h"
18 #include "clang/Basic/SourceLocation.h"
19 #include "clang/Sema/ExternalSemaSource.h"
20 #include "llvm/ADT/DenseMap.h"
21 #include "llvm/ADT/IntrusiveRefCntPtr.h"
22 #include "llvm/ADT/Optional.h"
23 #include "llvm/ADT/StringMap.h"
24 #include "llvm/ADT/StringRef.h"
25 #include <memory>
27 namespace clang {
28 namespace clangd {
30 /// Attempts to recover from error diagnostics by suggesting include insertion
31 /// fixes. For example, member access into incomplete type can be fixes by
32 /// include headers with the definition.
33 class IncludeFixer {
34 public:
35 IncludeFixer(llvm::StringRef File, std::shared_ptr<IncludeInserter> Inserter,
36 const SymbolIndex &Index, unsigned IndexRequestLimit)
37 : File(File), Inserter(std::move(Inserter)), Index(Index),
38 IndexRequestLimit(IndexRequestLimit) {}
40 /// Returns include insertions that can potentially recover the diagnostic.
41 /// If Info is a note and fixes are returned, they should *replace* the note.
42 std::vector<Fix> fix(DiagnosticsEngine::Level DiagLevel,
43 const clang::Diagnostic &Info) const;
45 /// Returns an ExternalSemaSource that records failed name lookups in Sema.
46 /// This allows IncludeFixer to suggest inserting headers that define those
47 /// names.
48 llvm::IntrusiveRefCntPtr<ExternalSemaSource> unresolvedNameRecorder();
50 private:
51 /// Attempts to recover diagnostic caused by an incomplete type \p T.
52 std::vector<Fix> fixIncompleteType(const Type &T) const;
54 /// Generates header insertion fixes for all symbols. Fixes are deduplicated.
55 std::vector<Fix> fixesForSymbols(const SymbolSlab &Syms) const;
57 llvm::Optional<Fix> insertHeader(llvm::StringRef Name,
58 llvm::StringRef Symbol = "") const;
60 struct UnresolvedName {
61 std::string Name; // E.g. "X" in foo::X.
62 SourceLocation Loc; // Start location of the unresolved name.
63 std::vector<std::string> Scopes; // Namespace scopes we should search in.
66 /// Records the last unresolved name seen by Sema.
67 class UnresolvedNameRecorder;
69 /// Attempts to fix the unresolved name associated with the current
70 /// diagnostic. We assume a diagnostic is caused by a unresolved name when
71 /// they have the same source location and the unresolved name is the last
72 /// one we've seen during the Sema run.
73 std::vector<Fix> fixUnresolvedName() const;
75 std::string File;
76 std::shared_ptr<IncludeInserter> Inserter;
77 const SymbolIndex &Index;
78 const unsigned IndexRequestLimit; // Make at most 5 index requests.
79 mutable unsigned IndexRequestCount = 0;
81 // These collect the last unresolved name so that we can associate it with the
82 // diagnostic.
83 llvm::Optional<UnresolvedName> LastUnresolvedName;
85 // There can be multiple diagnostics that are caused by the same unresolved
86 // name or incomplete type in one parse, especially when code is
87 // copy-and-pasted without #includes. We cache the index results based on
88 // index requests.
89 mutable llvm::StringMap<SymbolSlab> FuzzyFindCache;
90 mutable llvm::DenseMap<SymbolID, SymbolSlab> LookupCache;
91 // Returns None if the number of index requests has reached the limit.
92 llvm::Optional<const SymbolSlab *>
93 fuzzyFindCached(const FuzzyFindRequest &Req) const;
94 llvm::Optional<const SymbolSlab *> lookupCached(const SymbolID &ID) const;
97 } // namespace clangd
98 } // namespace clang
100 #endif // LLVM_CLANG_TOOLS_EXTRA_CLANGD_INCLUDEFIXER_H