Alex Lorenz | b54ef6a | 2017-09-14 10:06:52 +0000 | [diff] [blame] | 1 | //===--- TestSupport.h - Clang-based refactoring tool -----------*- 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 Declares datatypes and routines that are used by test-specific code |
| 12 | /// in clang-refactor. |
| 13 | /// |
| 14 | //===----------------------------------------------------------------------===// |
| 15 | |
| 16 | #ifndef LLVM_CLANG_TOOLS_CLANG_REFACTOR_TEST_SUPPORT_H |
| 17 | #define LLVM_CLANG_TOOLS_CLANG_REFACTOR_TEST_SUPPORT_H |
| 18 | |
Alex Lorenz | f5ca27c | 2017-10-16 18:28:26 +0000 | [diff] [blame] | 19 | #include "ToolRefactoringResultConsumer.h" |
Alex Lorenz | b54ef6a | 2017-09-14 10:06:52 +0000 | [diff] [blame] | 20 | #include "clang/Basic/LLVM.h" |
| 21 | #include "clang/Basic/SourceLocation.h" |
Alex Lorenz | b54ef6a | 2017-09-14 10:06:52 +0000 | [diff] [blame] | 22 | #include "llvm/ADT/Optional.h" |
| 23 | #include "llvm/ADT/SmallVector.h" |
| 24 | #include "llvm/Support/Error.h" |
| 25 | #include <map> |
| 26 | #include <string> |
| 27 | |
| 28 | namespace clang { |
| 29 | |
| 30 | class SourceManager; |
| 31 | |
| 32 | namespace refactor { |
| 33 | |
| 34 | /// A source selection range that's specified in a test file using an inline |
| 35 | /// command in the comment. These commands can take the following forms: |
| 36 | /// |
| 37 | /// - /*range=*/ will create an empty selection range in the default group |
| 38 | /// right after the comment. |
| 39 | /// - /*range a=*/ will create an empty selection range in the 'a' group right |
| 40 | /// after the comment. |
| 41 | /// - /*range = +1*/ will create an empty selection range at a location that's |
| 42 | /// right after the comment with one offset to the column. |
| 43 | /// - /*range= -> +2:3*/ will create a selection range that starts at the |
| 44 | /// location right after the comment, and ends at column 3 of the 2nd line |
| 45 | /// after the line of the starting location. |
| 46 | /// |
| 47 | /// Clang-refactor will expected all ranges in one test group to produce |
| 48 | /// identical results. |
| 49 | struct TestSelectionRange { |
| 50 | unsigned Begin, End; |
| 51 | }; |
| 52 | |
| 53 | /// A set of test selection ranges specified in one file. |
| 54 | struct TestSelectionRangesInFile { |
| 55 | std::string Filename; |
| 56 | struct RangeGroup { |
| 57 | std::string Name; |
| 58 | SmallVector<TestSelectionRange, 8> Ranges; |
| 59 | }; |
| 60 | std::vector<RangeGroup> GroupedRanges; |
| 61 | |
| 62 | TestSelectionRangesInFile(TestSelectionRangesInFile &&) = default; |
| 63 | TestSelectionRangesInFile &operator=(TestSelectionRangesInFile &&) = default; |
| 64 | |
| 65 | bool foreachRange(const SourceManager &SM, |
| 66 | llvm::function_ref<void(SourceRange)> Callback) const; |
| 67 | |
Alex Lorenz | f5ca27c | 2017-10-16 18:28:26 +0000 | [diff] [blame] | 68 | std::unique_ptr<ClangRefactorToolConsumerInterface> createConsumer() const; |
Alex Lorenz | b54ef6a | 2017-09-14 10:06:52 +0000 | [diff] [blame] | 69 | |
| 70 | void dump(llvm::raw_ostream &OS) const; |
| 71 | }; |
| 72 | |
| 73 | /// Extracts the grouped selection ranges from the file that's specified in |
| 74 | /// the -selection=test:<filename> option. |
| 75 | /// |
| 76 | /// The grouped ranges are specified in comments using the following syntax: |
| 77 | /// "range" [ group-name ] "=" [ "+" starting-column-offset ] [ "->" |
| 78 | /// "+" ending-line-offset ":" |
| 79 | /// ending-column-position ] |
| 80 | /// |
| 81 | /// The selection range is then computed from this command by taking the ending |
| 82 | /// location of the comment, and adding 'starting-column-offset' to the column |
| 83 | /// for that location. That location in turns becomes the whole selection range, |
| 84 | /// unless 'ending-line-offset' and 'ending-column-position' are specified. If |
| 85 | /// they are specified, then the ending location of the selection range is |
| 86 | /// the starting location's line + 'ending-line-offset' and the |
| 87 | /// 'ending-column-position' column. |
| 88 | /// |
| 89 | /// All selection ranges in one group are expected to produce the same |
| 90 | /// refactoring result. |
| 91 | /// |
| 92 | /// When testing, zero is returned from clang-refactor even when a group |
| 93 | /// produces an initiation error, which is different from normal invocation |
| 94 | /// that returns a non-zero value. This is done on purpose, to ensure that group |
| 95 | /// consistency checks can return non-zero, but still print the output of |
| 96 | /// the group. So even if a test matches the output of group, it will still fail |
| 97 | /// because clang-refactor should return zero on exit when the group results are |
| 98 | /// consistent. |
| 99 | /// |
| 100 | /// \returns None on failure (errors are emitted to stderr), or a set of |
| 101 | /// grouped source ranges in the given file otherwise. |
| 102 | Optional<TestSelectionRangesInFile> findTestSelectionRanges(StringRef Filename); |
| 103 | |
| 104 | } // end namespace refactor |
| 105 | } // end namespace clang |
| 106 | |
| 107 | #endif // LLVM_CLANG_TOOLS_CLANG_REFACTOR_TEST_SUPPORT_H |