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