Benjamin Kramer | 6b23626 | 2016-04-20 12:43:43 +0000 | [diff] [blame] | 1 | //===-- IncludeFixer.h - Include inserter -----------------------*- C++ -*-===// |
| 2 | // |
| 3 | // The LLVM Compiler Infrastructure |
| 4 | // |
| 5 | // This file is distributed under the University of Illinois Open Source |
| 6 | // License. See LICENSE.TXT for details. |
| 7 | // |
| 8 | //===----------------------------------------------------------------------===// |
| 9 | |
| 10 | #ifndef LLVM_CLANG_TOOLS_EXTRA_INCLUDE_FIXER_INCLUDEFIXER_H |
| 11 | #define LLVM_CLANG_TOOLS_EXTRA_INCLUDE_FIXER_INCLUDEFIXER_H |
| 12 | |
Haojian Wu | 11e9bd2 | 2016-05-31 09:31:51 +0000 | [diff] [blame] | 13 | #include "IncludeFixerContext.h" |
Benjamin Kramer | a3d8233 | 2016-05-13 09:27:54 +0000 | [diff] [blame] | 14 | #include "SymbolIndexManager.h" |
Haojian Wu | 11e9bd2 | 2016-05-31 09:31:51 +0000 | [diff] [blame] | 15 | #include "clang/Format/Format.h" |
Benjamin Kramer | cd2494e9 | 2016-11-17 15:16:05 +0000 | [diff] [blame] | 16 | #include "clang/Sema/ExternalSemaSource.h" |
Benjamin Kramer | 6b23626 | 2016-04-20 12:43:43 +0000 | [diff] [blame] | 17 | #include "clang/Tooling/Core/Replacement.h" |
| 18 | #include "clang/Tooling/Tooling.h" |
Eugene Zelenko | a54a212 | 2016-05-02 17:49:00 +0000 | [diff] [blame] | 19 | #include <memory> |
| 20 | #include <vector> |
Benjamin Kramer | 6b23626 | 2016-04-20 12:43:43 +0000 | [diff] [blame] | 21 | |
| 22 | namespace clang { |
Eugene Zelenko | a54a212 | 2016-05-02 17:49:00 +0000 | [diff] [blame] | 23 | |
| 24 | class CompilerInvocation; |
| 25 | class DiagnosticConsumer; |
| 26 | class FileManager; |
| 27 | class PCHContainerOperations; |
| 28 | |
Benjamin Kramer | 6b23626 | 2016-04-20 12:43:43 +0000 | [diff] [blame] | 29 | namespace include_fixer { |
| 30 | |
| 31 | class IncludeFixerActionFactory : public clang::tooling::ToolAction { |
| 32 | public: |
Benjamin Kramer | a3d8233 | 2016-05-13 09:27:54 +0000 | [diff] [blame] | 33 | /// \param SymbolIndexMgr A source for matching symbols to header files. |
Simon Pilgrim | 6cfad71 | 2016-08-09 10:02:11 +0000 | [diff] [blame] | 34 | /// \param Contexts The contexts for the symbols being queried. |
Eric Liu | 702cfd1 | 2016-05-19 08:21:09 +0000 | [diff] [blame] | 35 | /// \param StyleName Fallback style for reformatting. |
Benjamin Kramer | 3a45fab | 2016-04-28 11:21:29 +0000 | [diff] [blame] | 36 | /// \param MinimizeIncludePaths whether inserted include paths are optimized. |
Haojian Wu | 11e9bd2 | 2016-05-31 09:31:51 +0000 | [diff] [blame] | 37 | IncludeFixerActionFactory(SymbolIndexManager &SymbolIndexMgr, |
Haojian Wu | c99f728 | 2016-08-09 08:26:19 +0000 | [diff] [blame] | 38 | std::vector<IncludeFixerContext> &Contexts, |
| 39 | StringRef StyleName, |
Haojian Wu | 11e9bd2 | 2016-05-31 09:31:51 +0000 | [diff] [blame] | 40 | bool MinimizeIncludePaths = true); |
Eric Liu | 702cfd1 | 2016-05-19 08:21:09 +0000 | [diff] [blame] | 41 | |
Eugene Zelenko | a54a212 | 2016-05-02 17:49:00 +0000 | [diff] [blame] | 42 | ~IncludeFixerActionFactory() override; |
Benjamin Kramer | 6b23626 | 2016-04-20 12:43:43 +0000 | [diff] [blame] | 43 | |
| 44 | bool |
David Blaikie | e83806b | 2017-01-06 19:49:09 +0000 | [diff] [blame] | 45 | runInvocation(std::shared_ptr<clang::CompilerInvocation> Invocation, |
Benjamin Kramer | 6b23626 | 2016-04-20 12:43:43 +0000 | [diff] [blame] | 46 | clang::FileManager *Files, |
| 47 | std::shared_ptr<clang::PCHContainerOperations> PCHContainerOps, |
| 48 | clang::DiagnosticConsumer *Diagnostics) override; |
| 49 | |
| 50 | private: |
| 51 | /// The client to use to find cross-references. |
Benjamin Kramer | a3d8233 | 2016-05-13 09:27:54 +0000 | [diff] [blame] | 52 | SymbolIndexManager &SymbolIndexMgr; |
Benjamin Kramer | 6b23626 | 2016-04-20 12:43:43 +0000 | [diff] [blame] | 53 | |
Haojian Wu | c99f728 | 2016-08-09 08:26:19 +0000 | [diff] [blame] | 54 | /// Multiple contexts for files being processed. |
| 55 | std::vector<IncludeFixerContext> &Contexts; |
Benjamin Kramer | 3a45fab | 2016-04-28 11:21:29 +0000 | [diff] [blame] | 56 | |
| 57 | /// Whether inserted include paths should be optimized. |
| 58 | bool MinimizeIncludePaths; |
Eric Liu | 702cfd1 | 2016-05-19 08:21:09 +0000 | [diff] [blame] | 59 | |
| 60 | /// The fallback format style for formatting after insertion if no |
| 61 | /// clang-format config file was found. |
| 62 | std::string FallbackStyle; |
Benjamin Kramer | 6b23626 | 2016-04-20 12:43:43 +0000 | [diff] [blame] | 63 | }; |
| 64 | |
Haojian Wu | 62aee52 | 2016-07-21 13:47:09 +0000 | [diff] [blame] | 65 | /// Create replacements, which are generated by clang-format, for the |
| 66 | /// missing header and mising qualifiers insertions. The function uses the |
| 67 | /// first header for insertion. |
Haojian Wu | 11e9bd2 | 2016-05-31 09:31:51 +0000 | [diff] [blame] | 68 | /// |
| 69 | /// \param Code The source code. |
Haojian Wu | 62aee52 | 2016-07-21 13:47:09 +0000 | [diff] [blame] | 70 | /// \param Context The context which contains all information for creating |
| 71 | /// include-fixer replacements. |
Haojian Wu | 11e9bd2 | 2016-05-31 09:31:51 +0000 | [diff] [blame] | 72 | /// \param Style clang-format style being used. |
Haojian Wu | 62aee52 | 2016-07-21 13:47:09 +0000 | [diff] [blame] | 73 | /// \param AddQualifiers Whether we should add qualifiers to all instances of |
| 74 | /// an unidentified symbol. |
Haojian Wu | 11e9bd2 | 2016-05-31 09:31:51 +0000 | [diff] [blame] | 75 | /// |
Haojian Wu | 62aee52 | 2016-07-21 13:47:09 +0000 | [diff] [blame] | 76 | /// \return Formatted replacements for inserting, sorting headers and adding |
| 77 | /// qualifiers on success; otherwise, an llvm::Error carrying llvm::StringError |
| 78 | /// is returned. |
| 79 | llvm::Expected<tooling::Replacements> createIncludeFixerReplacements( |
Haojian Wu | c99f728 | 2016-08-09 08:26:19 +0000 | [diff] [blame] | 80 | StringRef Code, const IncludeFixerContext &Context, |
Haojian Wu | 62aee52 | 2016-07-21 13:47:09 +0000 | [diff] [blame] | 81 | const format::FormatStyle &Style = format::getLLVMStyle(), |
| 82 | bool AddQualifiers = true); |
Haojian Wu | 11e9bd2 | 2016-05-31 09:31:51 +0000 | [diff] [blame] | 83 | |
Benjamin Kramer | cd2494e9 | 2016-11-17 15:16:05 +0000 | [diff] [blame] | 84 | /// Handles callbacks from sema, does the include lookup and turns it into an |
| 85 | /// IncludeFixerContext. |
| 86 | class IncludeFixerSemaSource : public clang::ExternalSemaSource { |
| 87 | public: |
| 88 | explicit IncludeFixerSemaSource(SymbolIndexManager &SymbolIndexMgr, |
| 89 | bool MinimizeIncludePaths, |
| 90 | bool GenerateDiagnostics) |
| 91 | : SymbolIndexMgr(SymbolIndexMgr), |
| 92 | MinimizeIncludePaths(MinimizeIncludePaths), |
| 93 | GenerateDiagnostics(GenerateDiagnostics) {} |
| 94 | |
| 95 | void setCompilerInstance(CompilerInstance *CI) { this->CI = CI; } |
| 96 | void setFilePath(StringRef FilePath) { this->FilePath = FilePath; } |
| 97 | |
| 98 | /// Callback for incomplete types. If we encounter a forward declaration we |
| 99 | /// have the fully qualified name ready. Just query that. |
| 100 | bool MaybeDiagnoseMissingCompleteType(clang::SourceLocation Loc, |
| 101 | clang::QualType T) override; |
| 102 | |
| 103 | /// Callback for unknown identifiers. Try to piece together as much |
| 104 | /// qualification as we can get and do a query. |
| 105 | clang::TypoCorrection CorrectTypo(const DeclarationNameInfo &Typo, |
| 106 | int LookupKind, Scope *S, CXXScopeSpec *SS, |
| 107 | CorrectionCandidateCallback &CCC, |
| 108 | DeclContext *MemberContext, |
| 109 | bool EnteringContext, |
| 110 | const ObjCObjectPointerType *OPT) override; |
| 111 | |
| 112 | /// Get the minimal include for a given path. |
| 113 | std::string minimizeInclude(StringRef Include, |
| 114 | const clang::SourceManager &SourceManager, |
| 115 | clang::HeaderSearch &HeaderSearch) const; |
| 116 | |
| 117 | /// Get the include fixer context for the queried symbol. |
Benjamin Kramer | 87eb966 | 2016-11-21 15:28:50 +0000 | [diff] [blame] | 118 | IncludeFixerContext getIncludeFixerContext( |
| 119 | const clang::SourceManager &SourceManager, |
| 120 | clang::HeaderSearch &HeaderSearch, |
| 121 | ArrayRef<find_all_symbols::SymbolInfo> MatchedSymbols) const; |
| 122 | |
| 123 | /// Get the global matched symbols. |
| 124 | ArrayRef<find_all_symbols::SymbolInfo> getMatchedSymbols() const { |
| 125 | return MatchedSymbols; |
| 126 | } |
Benjamin Kramer | cd2494e9 | 2016-11-17 15:16:05 +0000 | [diff] [blame] | 127 | |
| 128 | private: |
| 129 | /// Query the database for a given identifier. |
Benjamin Kramer | 87eb966 | 2016-11-21 15:28:50 +0000 | [diff] [blame] | 130 | std::vector<find_all_symbols::SymbolInfo> |
| 131 | query(StringRef Query, StringRef ScopedQualifiers, tooling::Range Range); |
Benjamin Kramer | cd2494e9 | 2016-11-17 15:16:05 +0000 | [diff] [blame] | 132 | |
| 133 | CompilerInstance *CI; |
| 134 | |
| 135 | /// The client to use to find cross-references. |
| 136 | SymbolIndexManager &SymbolIndexMgr; |
| 137 | |
| 138 | /// The information of the symbols being queried. |
| 139 | std::vector<IncludeFixerContext::QuerySymbolInfo> QuerySymbolInfos; |
| 140 | |
| 141 | /// All symbol candidates which match QuerySymbol. We only include the first |
| 142 | /// discovered identifier to avoid getting caught in results from error |
| 143 | /// recovery. |
| 144 | std::vector<find_all_symbols::SymbolInfo> MatchedSymbols; |
| 145 | |
| 146 | /// The file path to the file being processed. |
| 147 | std::string FilePath; |
| 148 | |
| 149 | /// Whether we should use the smallest possible include path. |
| 150 | bool MinimizeIncludePaths = true; |
| 151 | |
| 152 | /// Whether we should generate diagnostics with fixits for missing symbols. |
| 153 | bool GenerateDiagnostics = false; |
| 154 | }; |
Benjamin Kramer | 6b23626 | 2016-04-20 12:43:43 +0000 | [diff] [blame] | 155 | } // namespace include_fixer |
| 156 | } // namespace clang |
| 157 | |
| 158 | #endif // LLVM_CLANG_TOOLS_EXTRA_INCLUDE_FIXER_INCLUDEFIXER_H |