1 //===--- TokenAnalyzer.h - Analyze Token Streams ----------------*- 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 /// \file 11 /// \brief This file declares an abstract TokenAnalyzer, and associated helper 12 /// classes. TokenAnalyzer can be extended to generate replacements based on 13 /// an annotated and pre-processed token stream. 14 /// 15 //===----------------------------------------------------------------------===// 16 17 #ifndef LLVM_CLANG_LIB_FORMAT_TOKENANALYZER_H 18 #define LLVM_CLANG_LIB_FORMAT_TOKENANALYZER_H 19 20 #include "AffectedRangeManager.h" 21 #include "Encoding.h" 22 #include "FormatToken.h" 23 #include "FormatTokenLexer.h" 24 #include "TokenAnnotator.h" 25 #include "UnwrappedLineParser.h" 26 #include "clang/Basic/Diagnostic.h" 27 #include "clang/Basic/DiagnosticOptions.h" 28 #include "clang/Basic/FileManager.h" 29 #include "clang/Basic/SourceManager.h" 30 #include "clang/Format/Format.h" 31 #include "llvm/ADT/STLExtras.h" 32 #include "llvm/Support/Debug.h" 33 34 namespace clang { 35 namespace format { 36 37 class Environment { 38 public: 39 Environment(SourceManager &SM, FileID ID, ArrayRef<CharSourceRange> Ranges) 40 : ID(ID), CharRanges(Ranges.begin(), Ranges.end()), SM(SM), 41 FirstStartColumn(0), 42 NextStartColumn(0), 43 LastStartColumn(0) {} 44 45 Environment(FileID ID, std::unique_ptr<FileManager> FileMgr, 46 std::unique_ptr<SourceManager> VirtualSM, 47 std::unique_ptr<DiagnosticsEngine> Diagnostics, 48 const std::vector<CharSourceRange> &CharRanges, 49 unsigned FirstStartColumn, 50 unsigned NextStartColumn, 51 unsigned LastStartColumn) 52 : ID(ID), CharRanges(CharRanges.begin(), CharRanges.end()), 53 SM(*VirtualSM), 54 FirstStartColumn(FirstStartColumn), 55 NextStartColumn(NextStartColumn), 56 LastStartColumn(LastStartColumn), 57 FileMgr(std::move(FileMgr)), 58 VirtualSM(std::move(VirtualSM)), Diagnostics(std::move(Diagnostics)) {} 59 60 // This sets up an virtual file system with file \p FileName containing the 61 // fragment \p Code. Assumes that \p Code starts at \p FirstStartColumn, 62 // that the next lines of \p Code should start at \p NextStartColumn, and 63 // that \p Code should end at \p LastStartColumn if it ends in newline. 64 // See also the documentation of clang::format::internal::reformat. 65 static std::unique_ptr<Environment> 66 CreateVirtualEnvironment(StringRef Code, StringRef FileName, 67 ArrayRef<tooling::Range> Ranges, 68 unsigned FirstStartColumn = 0, 69 unsigned NextStartColumn = 0, 70 unsigned LastStartColumn = 0); 71 72 FileID getFileID() const { return ID; } 73 74 ArrayRef<CharSourceRange> getCharRanges() const { return CharRanges; } 75 76 const SourceManager &getSourceManager() const { return SM; } 77 78 // Returns the column at which the fragment of code managed by this 79 // environment starts. 80 unsigned getFirstStartColumn() const { return FirstStartColumn; } 81 82 // Returns the column at which subsequent lines of the fragment of code 83 // managed by this environment should start. 84 unsigned getNextStartColumn() const { return NextStartColumn; } 85 86 // Returns the column at which the fragment of code managed by this 87 // environment should end if it ends in a newline. 88 unsigned getLastStartColumn() const { return LastStartColumn; } 89 90 private: 91 FileID ID; 92 SmallVector<CharSourceRange, 8> CharRanges; 93 SourceManager &SM; 94 unsigned FirstStartColumn; 95 unsigned NextStartColumn; 96 unsigned LastStartColumn; 97 98 // The order of these fields are important - they should be in the same order 99 // as they are created in `CreateVirtualEnvironment` so that they can be 100 // deleted in the reverse order as they are created. 101 std::unique_ptr<FileManager> FileMgr; 102 std::unique_ptr<SourceManager> VirtualSM; 103 std::unique_ptr<DiagnosticsEngine> Diagnostics; 104 }; 105 106 class TokenAnalyzer : public UnwrappedLineConsumer { 107 public: 108 TokenAnalyzer(const Environment &Env, const FormatStyle &Style); 109 110 std::pair<tooling::Replacements, unsigned> process(); 111 112 protected: 113 virtual std::pair<tooling::Replacements, unsigned> 114 analyze(TokenAnnotator &Annotator, 115 SmallVectorImpl<AnnotatedLine *> &AnnotatedLines, 116 FormatTokenLexer &Tokens) = 0; 117 118 void consumeUnwrappedLine(const UnwrappedLine &TheLine) override; 119 120 void finishRun() override; 121 122 FormatStyle Style; 123 // Stores Style, FileID and SourceManager etc. 124 const Environment &Env; 125 // AffectedRangeMgr stores ranges to be fixed. 126 AffectedRangeManager AffectedRangeMgr; 127 SmallVector<SmallVector<UnwrappedLine, 16>, 2> UnwrappedLines; 128 encoding::Encoding Encoding; 129 }; 130 131 } // end namespace format 132 } // end namespace clang 133 134 #endif 135