xref: /netbsd-src/external/apache2/llvm/dist/clang/tools/clang-refactor/TestSupport.h (revision 7330f729ccf0bd976a06f95fad452fe774fc7fd1)
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