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