blob: 101f35bd94f3cf41605dcdd745e3dcef726f6b29 [file] [log] [blame]
Alex Lorenzb54ef6a2017-09-14 10:06:52 +00001//===--- 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 Lorenzf5ca27c2017-10-16 18:28:26 +000019#include "ToolRefactoringResultConsumer.h"
Alex Lorenzb54ef6a2017-09-14 10:06:52 +000020#include "clang/Basic/LLVM.h"
21#include "clang/Basic/SourceLocation.h"
Alex Lorenzb54ef6a2017-09-14 10:06:52 +000022#include "llvm/ADT/Optional.h"
23#include "llvm/ADT/SmallVector.h"
24#include "llvm/Support/Error.h"
25#include <map>
26#include <string>
27
28namespace clang {
29
30class SourceManager;
31
32namespace 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.
49struct TestSelectionRange {
50 unsigned Begin, End;
51};
52
53/// A set of test selection ranges specified in one file.
54struct 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 Lorenzf5ca27c2017-10-16 18:28:26 +000068 std::unique_ptr<ClangRefactorToolConsumerInterface> createConsumer() const;
Alex Lorenzb54ef6a2017-09-14 10:06:52 +000069
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.
102Optional<TestSelectionRangesInFile> findTestSelectionRanges(StringRef Filename);
103
104} // end namespace refactor
105} // end namespace clang
106
107#endif // LLVM_CLANG_TOOLS_CLANG_REFACTOR_TEST_SUPPORT_H